3

HTTP とは異なり、websocket は HTTP からアップグレードされた後も長期間接続を維持します。

OS がすべてのポートを使用するように調整されている場合でも、合計で 65536 ポートしかありません。NGINX がこの制限を超える可能性はありますか?

潜在的な解決策は ですがSO_REUSEPORT、ドキュメントが不足しています -- 少なくとも次の段落以外は見つかりません

NGINX リリース 1.9.1 には、SO_REUSEPORT ソケット オプションの使用を可能にする新しい機能が導入されています。これは、DragonFly BSD および Linux (カーネル バージョン 3.9 以降) を含む多くのオペレーティング システムの新しいバージョンで使用できます。このソケット オプションを使用すると、複数のソケットが同じ IP アドレスとポートの組み合わせでリッスンできます。次に、カーネルはソケット間で着信接続の負荷を分散します。

そのため、NGINX はacceptインバウンド接続を受け入れるように呼び出します。

accept() システム コールは、接続ベースのソケット タイプ (SOCK_STREAM、SOCK_SEQPACKET) で使用されます。リッスン ソケット sockfd の保留中の接続のキューで最初の接続要求を抽出し、新しい接続済みソケットを作成し、そのソケットを参照する新しいファイル記述子を返します。新しく作成されたソケットはリッスン状態ではありません。元のソケット sockfd は、この呼び出しの影響を受けません。

新しいソケットはポートを消費しますか? はいの場合、65535 接続制限を超えるにはどうすればよいですか?

4

1 に答える 1

3

あなたが受け取ったコメントは正しいです:

TCP 接続は、4 つのタプル (src_addr、src_port、dst_addr、dst_port) によって定義されます。クライアントが異なる IP アドレスや送信元ポートを使用している場合、サーバーを 65536 を超えるクライアントにすべて同じポートで接続できます。例: サーバー IP はポート 80 でリッスンする 0.0.0.1 です。この場合、4 つのタプルはすべて (*, *, 0.0.0.1, 80) になります。同じ 4 タプルがない限り、サーバーはポート 80 でメモリが許す限り多くの接続を持つことができます。— トウモロコシの茎

ただし、制限を超えるかどうかを評価するときは、nginx が単なるサーバーではないことも考慮する必要があります ( ngx_connection.c#ngx_open_listening_sockets()call socket(2)bind(2)およびlisten(2)のようなポートを引き継ぐためのシステム コールが80あり、その後accept(2)無限ループで呼び出す)。また、アップストリーム サーバーのクライアントである可能性もあります (必要に応じて、8080 などのポートでアップストリームを呼び出して接続します) socket(2)connect(2)

サーバー コンテキストでは TCP ポートが不足することはあり得ませんが (サーバーはすべての接続で 1 つのポートを使用するため、ポート 80 など)、クライアント側で TCP ポートが不足することは現実的であることに注意してください。構成によっては可能性があります。また、クライアントがclose(2)接続を行った後、状態がTIME_WAIT約 60 秒程度続くことを考慮する必要があります (遅れて到着したパケットが通過した場合に、システムが何をすべきかを確実に認識できるようにするため)。彼らと一緒に)。

ただし、そうは言っても、少なくとも参照されているリリース ノートとnginx 1.9.1 の発表で示されているシャーディングコンテキストでは、へSO_REUSEPORTオプションはジレンマとはまったく関係がないことに注意してください。カーネルとカーネルの下で実行されているアプリケーション間のサポート:getsockopt(2)reuseport65535

36 コアの AWS インスタンスで 4 つの NGINX ワーカーを使用して wrk ベンチマークを実行しました。ネットワークの影響を排除するために、localhost でクライアントと NGINX の両方を実行し、NGINX がファイルではなく文字列 OK を返すようにしました。私は 3 つの NGINX 構成を比較しました: デフォルト (accept_mutex オンに相当)、accept_mutex オフ、reuseport あり。図に示すように、reuseport は 1 秒あたりのリクエスト数を 2 ~ 3 倍に増やし、レイテンシとレイテンシの標準偏差の両方を削減します。

nginx 1.9.1 での再利用ポートのベンチマーク

あなたの根底にある質問に関しては、uint16_t送信TCPポートの問題の解決策は、おそらく、これが懸念される場合にTCPを介してバックエンドを使用しないこと、および/またはproxy_bindet al ディレクティブを介して追加のローカルアドレスを使用することです(および/または数を制限することです)バックエンドで確立できる TCP 接続の数)。

于 2016-07-05T17:23:41.343 に答える