web-dev-qa-db-ja.com

Spring WebFluxおよびReactorのスレッドモデル

現在、Spring 5.0.0.RC2Reactor 3.1.0.M2、およびSpring Boot 2.0.0.M2でリアクティブプログラミングを実験しています。

同時実行およびスレッドモデルについて疑問に思うことは、アプリケーションを適切にコーディングし、可変状態を処理するためにWebFluxおよびReactorによって使用されます。

Reactorのドキュメントでは、ライブラリは同時実行不可と見なされ、スケジューラの抽象化について言及しています。 WebFluxドキュメントは情報を提供しません。

ただし、Spring BootでWebFluxを使用する場合、スレッドモデルが定義されます。

私の実験から得たものは次のとおりです。

  • モデルは1つのイベントスレッドでも、1つのイベントスレッド+ワーカーでもありません
  • いくつかのスレッドプールが使用されます
  • reactor-http-nio-3」スレッド:おそらくコアごとに1つ、着信HTTP要求を処理します
  • Thread-7」スレッド:MongoDBまたはHTTPリソースへの非同期リクエストで使用
  • parallel-1」スレッド:ReactorのSchedulers.parallel()によって作成され、遅延演算子などによって使用される、コアごとに1つ
  • 共有可変状態は、アプリケーションによって同期される必要があります
  • ThreadLocal(アプリケーションの状態、MDCロギングなど)は要求スコープではないため、あまりおもしろくない

これは正しいです ? WebFluxの同時実行およびスレッドモデルとは何ですか?たとえば、デフォルトのスレッドプールとは何ですか?

情報ありがとうございました

21

質問の後、 現在のドキュメントは同時実行モデルに関するいくつかの手がかりを提供します と期待できるスレッド(しかし、私はまだ、スレッドの観点は、Springの新規参入者に高く評価されます)。

Spring MVCとSpring WebFluxの違いについて説明します(リクエストごとの1スレッドモデルとイベントループ)。

Spring MVC、および一般的なサーブレットアプリケーションでは、アプリケーションが現在のスレッドをブロックすることが想定されています。リモート呼び出しの場合、およびそのため、サーブレットコンテナは大きなスレッドプールを使用して、要求処理中の潜在的なブロッキングを吸収します。

Spring WebFlux、および一般的な非ブロッキングサーバーでは、アプリケーションはブロックしないと想定されているため、非ブロッキングサーバーは小さな固定サイズのスレッドプール(イベントループワーカー)を使用してリクエストを処理します。ブロッキングAPIの呼び出し

ただし、Spring MVCアプリでは非同期性が生じる可能性があることに注意してください(Servlet 3 Asyncを参照)。そして、私は このプレゼンテーション Servlet 3.1 NIOとWebFluxについての議論を提案します。

ドキュメントに戻る:また、リアクティブストリームを操作する場合、次のような制御が可能であることも示唆しています。

ブロッキングライブラリを使用する必要がある場合はどうなりますか?

ReactorとRxJavaの両方が、異なるスレッドで処理を続行するためのpublishOnオペレーターを提供します。

(これについての詳細は、 Reactorでのスケジューリング を参照してください)

また、WebFluxアプリケーションで予想されるスレッドについても説明します(boldは私のものです):

スレッドモデル

Spring WebFluxを実行しているサーバー上でどのスレッドを表示する必要がありますか?

  • 「Vanilla」Spring WebFluxサーバー(データアクセスやその他のオプションの依存関係なし)では、サーバーのスレッドが1つ、リクエスト処理のスレッドがいくつか(通常、 CPUコアの数)。ただし、サーブレットコンテナは、より多くのスレッド(Tomcatで10など)で開始し、サーブレット、I/Oおよびサーブレット3.1のブロック、非ブロックI/O使用の両方をサポートする場合があります。
  • リアクティブWebClientは、イベントループスタイルで動作します。そのため、それに関連する処理スレッドの小さな固定数が表示されます。 Reactor Nettyコネクターを使用した「reactor-http-nio-」。ただし、Reactor Nettyがクライアントとサーバーの両方に使用される場合、2つはデフォルトでイベントループリソースを共有します。
  • ReactorとRxJavaは、Schedulersと呼ばれるスレッドプール抽象化を提供し、処理の切り替えに使用されるpublishOn演算子と共に使用します。別のスレッドプールにスケジューラーには、特定の並行性戦略を示唆する名前がありますスレッド数が制限されたCPUバウンドワークの場合は「並列」、またはI/Oの場合は「弾性」多数のスレッドを含む-bound work。このようなスレッドが表示される場合、特定のコードが特定のスレッドプールスケジューラ戦略を使用していることを意味します。
  • データアクセスライブラリと他のサードパーティの依存関係も、独自のスレッドを作成して使用する場合があります

一部では、構成を介してスレッドモデルの詳細を構成できます。

サーバーのスレッドモデルを構成するには、サーバー固有の構成APIを使用する必要があります。SpringBootを使用している場合は、各サーバーのSpring Boot構成オプションを確認してください。 WebClientは直接設定できます。他のすべてのライブラリについては、それぞれのドキュメントを参照してください。

さらに、例えば議論 Springブート2.0リアクティブwebflux構成のデフォルトのスレッド数 ハイライト、

要求処理のデフォルトのスレッド数は、基盤となるWebサーバーによって決定されます。デフォルトでは、Spring Boot 2.0はReactor Nettyを使用しており、これはNettyのデフォルトを使用しています

それはデフォルトのコンポーネントとそのデフォルト(およびアノテーションを介して透過的に挿入されたものを含む全体的な構成)の問題です-これはSpring/Bootのバージョンと対応する依存関係によっても変わる可能性があります。そうは言っても、あなたの推測は正しいようです。

17
metaphori