5分で書かれた非常に単純なプログラムで、サーバーソケットを開き、リクエストをループして、送信されたバイトを画面に出力します。
次に、このプログラムでサポートできる同時接続ユーザー数を調べるために、接続できる接続数をベンチマークしてみました。
別のマシン(それらの間のネットワークが飽和していない)で、ループに入ってサーバーマシンに接続し、バイト「hello world」を送信する簡単なプログラムを作成しました。
ループが1000〜3000の場合、クライアントはすべての要求を送信して終了します。ループが5000を超えると、最初のX個の要求が終了した後にタイムアウトが発生し始めます。どうしてこれなの?ループ内のソケットを必ず閉じてください。
特定の期間内に非常に多くの接続のみを作成できますか?
この制限は同じマシン間でのみ適用され、5000以上のリクエストがすべて異なるマシンから送信される実稼働環境でこれを心配する必要はありませんか?
はい、制限があります。 ulimit
を参照してください。
また、TIMED_WAIT
状態を考慮する必要があります。 TCPソケットが閉じられた場合(デフォルト)、ポートはTIMED_WAIT
ステータスで2分間占有のままです。この値は調整可能です。これも調整可能です。閉じられていても、ソケットを使い果たしてしまいます。
netstat
を実行して、TIMED_WAIT
の動作を確認します。
追伸TIMED_WAIT
の理由は、ソケットが閉じられた後に到着するパケットのケースを処理するためです。これは、パケットが遅延しているか、相手側がソケットがまだ閉じられていることを知らないために発生する可能性があります。これにより、OSは、関連のない別のソケット接続に「感染」することなく、これらのパケットを静かにドロップできます。
最大のパフォーマンスを探していると、多くの問題と潜在的なボトルネックが発生します。単純なHello Worldテストを実行しても、必ずしもすべてが見つかるとは限りません。
可能な制限は次のとおりです。
/proc/sys/net
多数のカーネルチューニング用。ulimit
をチェックしてくださいtop
を使用して、CPUが最大になっているかどうかを確認しますサーバーはシングルスレッドですか?その場合、どのポーリング/多重化機能を使用していますか?
Select()の使用は、コンパイル時に設定されたハードコードされた最大ファイル記述子の制限を超えて機能しません。これは絶望的です(通常256またはそれ以上)。
poll()の方が優れていますが、ループのたびに多数のFDがセットを再配置するというスケーラビリティの問題が発生します。
epoll()は、ヒットした他の制限までうまく機能するはずです。
10kの接続は、簡単に実現できます。最近の(ish)2.6カーネルを使用します。
何台のクライアントマシンを使用しましたか?クライアント側の制限に達していませんか?
簡単な答えは2 ^ 16 TCPポート、64Kです。
システムによって課される制限の問題は構成の問題であり、以前のコメントで既に触れました。
TCPへの内部的な意味はそれほど明確ではありません(私にとって)。各ポートは、インスタンス化のためにメモリを必要とし、リストに追加され、送信中のデータ用のネットワークバッファを必要とします。
64K TCPセッションの場合、ポートのインスタンスのオーバーヘッドは32ビットカーネルでは問題になる可能性がありますが、64ビットカーネルでは問題になりません(ここでの修正は喜んで受け入れられます)。 64Kセッションでのルックアッププロセスでは、処理が少し遅くなり、すべてのパケットがタイマーキューにヒットする可能性があり、これも問題になる可能性があります。転送中のデータのストレージは、理論的には、ウィンドウサイズとポート(8ギガバイト)の積に膨らむことがあります。
接続速度(上記)の問題は、おそらく見ているものです。 TCPは通常、処理に時間がかかります。ただし、必須ではありません。 TCP接続、トランザクション、および切断は非常に効率的に実行できます(TCPセッションがどのように作成され、閉じられるかを確認してください)。
毎秒数十ギガビットを渡すシステムがあるため、パケットレベルのスケーリングは問題ないはずです。
十分な物理メモリを備えたマシンがありますので、見た目は問題ありません。
システムのパフォーマンスは、慎重に構成されていれば問題ありません。
サーバー側も同様の方法でスケーリングする必要があります。
私はメモリ帯域幅のようなものを心配するでしょう。
ローカルホストに10,000回ログインする実験を検討してください。次に、文字を入力します。ユーザー空間を通るスタック全体が各キャラクターに関与します。アクティブなフットプリントは、データキャッシュサイズを超える可能性があります。大量のメモリを実行すると、VMシステムに負荷がかかる可能性があります。コンテキスト切り替えのコストは1秒に迫る可能性があります!
これは他のさまざまなスレッドで説明されています: https://serverfault.com/questions/69524/im-designing-a-system-to-handle-10000-tcp-connections-per-second-what-問題
/etc/security/limits.confをチェックアウトしたいかもしれません
はい、制限はカーネルによって設定されます。詳細については、Stack Overflowでこのスレッドを確認してください。 Linuxでのtcp/ip接続の最大数を増やす