TCP サーバー アプリケーションで使用されるスレッドの数を最小限にするにはどうすればよいですか?
-
09-06-2019 - |
質問
クライアントの TCP (または UDP) リクエストにサービスを提供するサーバー アプリケーションを実装するときに人々が使用する戦略を探しています。デザインパターン、実装テクニック、ベストプラクティスなど。
この質問の目的として、リクエストの存続期間が比較的長く (数分)、トラフィックは時間に敏感であるため、メッセージへの応答に遅延は許容されないと仮定します。また、クライアントからのリクエストを処理し、他のサーバーへの独自の接続を確立します。
私のプラットフォームは .NET ですが、基盤となるテクノロジーはプラットフォームに関係なく同じであるため、どの言語でも答えを知りたいと思っています。
解決
最新のアプローチは、オペレーティング システムを利用して多くのネットワーク ソケットを多重化し、アプリケーションがトラフィックのあるアクティブな接続のみを処理できるようにすることです。
ソケットを開くたびに、ソケットはセレクターに関連付けられます。単一のスレッドを使用してそのセレクターをポーリングします。データが到着すると、セレクターはアクティブなソケットを示し、その操作を子スレッドに渡してポーリングを続行します。
この方法では、同時操作ごとにスレッドのみが必要になります。開いているがアイドル状態のソケットはスレッドを拘束しません。
他のヒント
より洗練されたアプローチは、IO Completion ポートを使用することです。(ウィンドウズ) IO 完了ポートを使用すると、ポーリングの管理をオペレーティング システムに任せることができるため、オペレーティング システムは NIC ドライバーのサポートにより、非常に高いレベルの最適化を使用できる可能性があります。基本的に、OS によって管理されるネットワーク操作のキューがあり、操作が完了したときに呼び出されるコールバック関数を提供します。(ハードドライブの) DMA に少し似ていますが、ネットワーク用です。
Len Holgate は、数年前に Codeproject で IO 完了ポートに関する素晴らしいシリーズを書きました。http://www.codeproject.com/KB/IP/jbsocketserver2.aspx
そして .netのIO補完ポートに関する記事を見つけました(まだ読んでいませんが) http://www.codeproject.com/KB/cs/managediocp.aspx
また、スケーラブルな代替案を作成してみるよりも、完了ポートを使用する方が簡単だとも思います。問題は、NT (2000、XP、Vista) でのみ利用できることです。
C++ と Win32 を直接使用している場合は、重複する I/O ポートと I/O 完了ポートについて読むことをお勧めします。完全なソース コードを備えた無料の C++、IOCP、クライアント/サーバー フレームワークを持っています。 を参照してください。 ここ 詳細については。
.Net を使用しているので、接続ごとにスレッドを用意する必要がないように、非同期ソケット メソッドの使用を検討する必要があります。私のこのブログ投稿からは、開始点として役立つリンクがいくつかあります。 http://www.lenholgate.com/blog/2005/07/disappointing-net-sockets-article-in-msdn-magazine-this-month.html (最良のリンクの一部は、元の投稿へのコメントにあります。)
こんにちは、
まず、スレッド フレームワークに使用するメタファーを検討します。
おそらく、スレッドが着信リクエストをリッスンし、新しいリクエストが到着するとそのスレッドが作業を実行し、プール内の次のスレッドが着信リクエストのリスニングを開始する「リーダーフォロワー」の場合があります。
または、同じスレッドが常に着信リクエストをリッスンし、スレッド プール内の次に利用可能なスレッドにリクエストを渡すスレッド プール。
ぜひ訪れてみてはいかがでしょうか リアクター Ace コンポーネントのセクションを参照してアイデアを得ることができます。
HTH。
乾杯 奪う