8

ソケットプログラミングでマルチクライアント機能をサポートするための複数のスレッドを作成できます。それはうまく機能しています。しかし、10,000のクライアントが接続したい場合、私のサーバーはそれほど多くのスレッドを作成できません。

これらすべてのクライアントを同時にリッスンできるようにスレッドを管理するにはどうすればよいですか?

また、この場合、サーバーが特定のクライアントに何かを送信したい場合、それはどのように可能ですか?

4

9 に答える 9

11

ノンブロッキング ネットワーク プログラミングについては、Java の NIO ("New I/O") ライブラリを調査する必要があります。NIO は、あなたが直面しているサーバーのスケーラビリティの問題を正確に解決するように設計されています!

于 2009-03-31T05:25:41.663 に答える
8

Java での高度にスケーラブルなソケット プログラミングには、「New I/O」または NIO パッケージで提供される選択可能なチャネルが必要です。ノンブロッキング IO を使用することで、1 つのスレッドが多くのソケットにサービスを提供し、準備ができているソケットのみを処理できます。

よりスケーラブルなオープンソース NIO アプリケーションの 1 つは、Glassfish アプリケーション サーバーのGrizzlyコンポーネントです。Jean-Francois Arcandは、このプロジェクトでの彼の作業について有益で詳細なブログ投稿を多数書いており、NIO でこの種のソフトウェアを作成する際の多くの微妙な落とし穴について説明しています。

ノンブロッキング IO の概念が初めての場合は、Grizzly などの既存のソフトウェアを使用するか、少なくともそれを適応の出発点として使用すると、非常に役立つ場合があります。

于 2009-03-31T05:25:08.500 に答える
6

NIO の利点については議論の余地があります。Paul Tyma のブログ エントリを参照してくださいここおよびここ.

于 2009-03-31T16:08:16.143 に答える
4

接続ごとのスレッド モデル (ブロッキング ソケット I/O) は、あまりうまく拡張できません。Java でノンブロッキング ソケット呼び出しを使用できるようにする Java NIO の概要を以下に示します: http://today.java.net/cs/user/print/a/350

記事にあるように、利用可能なフレームワークはたくさんあるので、自分で作成する必要はありません。

于 2009-03-31T05:26:47.513 に答える
2

前述のように、10,000 のクライアントは簡単ではありません。Java の場合、NIO (NIO スレッドをブロックせずに各要求を処理するために別個のスレッドプールで強化される可能性があります) は、大量のクライアントを処理する通常の方法です。

前述のように、実装によってはスレッドが実際にスケーリングされる場合がありますが、それはクライアント接続間のやり取りの量に大きく依存します。スレッド間の同期がほとんどない場合、大量のスレッドが機能する可能性が高くなります。

とは言うものの、NIO を最初に実装したときに 100% 正しく動作することは非常に難しいことで知られています。

試してみるか、少なくともnaga.googlecode.comにある Naga NIO lib のソースを確認することをお勧めします。lib のコードベースは、他のほとんどの NIO フレームワークに比べて小さいです。10.000 クライアントを起動して実行できるかどうかを確認するテストをすばやく実装できるはずです。

(Naga のソースもたまたま、元の作者を特定せずに自由に変更またはコピーできます)

于 2009-04-01T20:55:01.470 に答える
1

これは単純な質問ではありませんが、非常に詳細な (申し訳ありませんが、java ではありません) 回答については、http ://www.kegel.com/c10k.html を参照してください。


編集

nioでも、これはまだ難しい問題です。ノンブロッキング ソケットを使用している場合でも、10000 接続はマシンのリソースに多大な負荷をかけます。これが、大規模な Web サイトにサーバー ファームとロード バランサーがある理由です。

于 2009-03-31T05:24:47.877 に答える
1

一度に一定量のリクエストのみを処理してみませんか。

一度に最大 50 個のリクエストを処理したいとします (スレッドを作成しすぎないようにするため)。

50 スレッドのスレッドプールを作成します。

すべてのリクエストをキューに入れ(接続を受け入れ、ソケットを開いたままにする)、各スレッドが完了すると、次のリクエストを取得して処理します。

これにより、より簡単にスケーリングできます。

また、必要に応じて、複数のサーバーでキューを共有できるため、負荷分散が簡単になります。

于 2009-03-31T16:04:56.120 に答える
0

個人的には、カスタム I/O 非ブロック設定を作成することをお勧めします。たとえば、1 つのスレッドを使用してクライアントを受け入れ、別の 1 つのスレッドを使用してそれらを処理します (入力が利用可能かどうかを確認し、必要に応じて出力にデータを書き込みます)。

于 2009-07-02T16:40:43.043 に答える
0

アプリケーションが 10,000 スレッドで失敗する理由を突き止める必要があります。

  1. JVM または OS のスレッド数に厳しい制限はありますか? その場合、持ち上げることはできますか?

  2. メモリ不足ですか?スレッドあたりのスタック サイズを小さく設定するか、サーバーにメモリを追加してみてください。

  3. 他の何か?修理する。

問題の原因を突き止めて初めて、それを修正することができます。理論上は 10,000 スレッドで問題ありませんが、そのレベルの同時実行性でうまく動作させるには、JVM とオペレーティング システムをさらに調整する必要があります。

NIO も検討できますが、スレッドでも問題なく動作すると思います。

于 2012-03-24T13:02:55.117 に答える