web-dev-qa-db-ja.com

サーブレットベースのweb-mvcアプリにおけるRestTemplateとWebClientのメリット

以下のステートメントの太字のテキストについての説明を探しています(コンテキストのみの段落全体を提供しました)。

RestTemplateは非ブロッキングアプリケーションでの使用には適していないため、Spring WebFluxアプリケーションは常にWebClientを使用する必要があります。 WebClientは、Spring MVC、ほとんどの同時実行シナリオ、およびリモートの相互依存呼び出しのシーケンスを構成する場合にも推奨されます。

ここにあります: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html

特に、Spring MVCアプリでWebClientよりもRestTemplateを使用する利点は何ですか?適切に構成された接続とソケット構成でApache WebClientRestTemplateを構成したHttpClientと比較して、どのようにPoolingHttpClientConnectionManagerより高いスケールを実現しますか?

7
Kevin

WebClientは非ブロッキングですが、RestTemplateはブロッキング/同期です。ノンブロッキングWebFlux APIをブロッキングライブラリと共に使用している場合は、本質的にそれをブロッキングAPIに変換しています。

RestTemplateは、実際に各イベントの新しいThreadを作成するものと考え、vs WebClientTask(まるでqueueのように、これは基本的にReactorが背後で管理するものです)。 Threadの飢餓にすぐに到達します。すべての非ブロッキングタスクに対して、それをサポートするブロッキングコールがある場合(各RestTemplate; ConnectionManagerへの委任は引き続きブロック呼び出しを行っていることに注意してください)。一方、Taskqueuedをリアクティブフレームワークによって取得し、適切なリソースが利用可能になると実行されます。

Spring MVCでWebClientを使用する理由

WebClientは非ブロッキングです!すべてのFlux機能を使用できます(pub-sub、backpressureなど)。これはリソースを節約するのに役立ちます(つまり、使用するスレッドとメモリを減らします)。Reactorを使用すると、使用していないスレッドの使用を最大化できます。ここでの質問は、Spring MVCで実際に「なぜWebClientを使用する必要があるのか​​」ではなく、アプリケーションで「なぜリアクティブ/非ブロッキング」フレームワークを使用する必要があるのか​​という問題です。この質問のインターネット上のたくさんの例( これは1つ )とその答えです。

MonoおよびFluxは、非反応性の非ブロッキング構造を使用する場合、 Java 8 CompletableFuture も返すことができます。

WebFluxでWebClientを使用する理由

あなたのページからこの引用を参照してください そのドキュメントで参照されています

WebClientWebFluxサーバーアプリケーションと同じコーデックを使用し、共通基本パッケージ、いくつかの共通API、およびサーバー機能Webフレームワークを備えたインフラストラクチャ。 APIはReactorFluxおよびMonoタイプを公開します

ここで重要なのは、WebClientFluxと同じ反応的な非ブロッキングタイプを使用することです。そのため、統合は非常にうまく行われ、Niceタスク機能が利用できます。例(そして、私は that doc からコードのチャンクを借りています):

WebClient client = WebClient.create("http://example.org");
Mono<Void> result = client.post()
        .uri("/persons/{id}", id)
        .contentType(MediaType.APPLICATION_JSON)
        .body(personMono, Person.class)
        .retrieve()
        .bodyToMono(Void.class);

そのコードがMonoをどのように生成するかをご覧ください。これは、WebFluxbuilt onであるリアクティブなコンストラクトであり、それがフレームワークで使用する理由です。たとえば、実際に Mono呼び出しでControllerを反応的に返す

@PostMapping("/person")
Mono<Void> create(@RequestBody Publisher<Person> personStream) {
     // ... above code could go here...
     return result; 
}

この種のことが、WebClientライブラリでWebFluxを使用する必要があると彼らが言う主な理由です。

5
Dovmo

少し調べた結果、答えはSpringの DeferredResult にあると思います。これから少し言い回しを盗む blog

DeferredResultは、将来利用可能になる可能性のある、まだ完了していない可能性のある計算のコンテナーです。 Spring MVCはこれを使用して非同期計算を表し、Servlet 3.0のAsyncContext非同期リクエスト処理を利用します。

私はWebFluxの前に何が起こったと思います。このDeferredResultの概念は、非同期のサポートの最初のカットでしたIO Spring MVCの内部、たとえば、非推奨になった AsyncRestTemplate もあります) ListenableFutureラッパーを返します。

つまり、これは、比較的単純なREST Spring MVCでAPIを使用している場合、DeferredFutureを介して非同期に結果を生成するWebClientを返す可能性があることを意味します。したがって、Spring MVCから移行せずに非同期処理のいくつかの利点を得ることができます(一部のプロジェクトでは実行できない場合があります)。

0
Kevin