ロードバランサーは、実行中のプラットフォームに基づいて、同時に使用できる tcp ポートの数に制限があります (たとえば、Linux では最大 65535 の tcp ポートを同時に開くことができるとどこかで読みました)。これは、バランサーがボトルネックになり、バックエンド サーバー ファームがより多くの要求を同時に処理できる場合でも、それらの多くの同時要求を超えて処理できないことを意味します。この問題を克服する方法はありますか?
1 に答える
TCP と UDP のポート番号は 16 ビットなので、特定の IP には 65535 しかありません (ポート 0 は有効ではないと思います)。ただし、TCP 接続は 4 つのタプル (送信元 IP、送信元ポート、宛先 IP、宛先ポート) によって識別されます。(ウィキペディアに詳細へのリンクがあるようです。)
client->balancer リクエストの場合: 各インバウンド接続に個別の (送信元 IP、送信元ポート) がある限り、問題はありません。そして、クライアントは通常これを保証します。私が聞いたことを覚えているこの側の唯一の問題は、非常に人気のあるWebサイトで、非常に少数のIPv4アドレスの背後で顧客をNATする巨大なISPからアクセスすると、ページごとに多くの画像が表示されることでした. それはおそらくあなたの状況ではありません。
上記の NAT の問題と同様の状況を作成している可能性があるため、バランサー -> バックエンド リクエストはより興味深いものです。Linux は通常、各ソケットに個別のエフェメラル ポートを割り当てようとしますが、デフォルトでは 28,233 個しかありません。また、IIRCは状態のものも使用しないため、TIME_WAIT
実際に多くの接続を同時に開かなくても範囲を使い果たすことができます。この制限に達すると、IIRC でEADDRINUSE
エラーが発生しますconnect
(または、bind
接続する前に明示的にソケットをバインドする場合は on)。以前にこれをどのように回避したかは正確には覚えていませんが、絶対的な最善の方法は言うまでもありませんが、役立つ可能性のあるいくつかのことを次に示します。
- 各クライアント -> バランサー接続 (おそらく短命) ごとに新しい接続を作成するのではなく、永続的なバランサー -> バックエンド接続を維持します。
- /
SO_REUSEADDR
の前のソケットの設定。bind
connect
net.ipv4.tcp_tw_reuse
sysctlおよび/またはをオンにしnet.ipv4.tcp_tw_recycle
ます。bind
カーネルに自動割り当てさせるのではなく、経由で使用するソース IP やポートを明示的に選択しconnect
ます。同じ 4 タプルで 2 つの同時接続を行うことはできませんが、それ以外は問題ありません。(例外: 私はTIME_WAIT
、同じ 4 タプルの再利用が問題ないかどうかを熟考しTIME_WAIT
ています。いくつかの TCP RFC を読んで記憶をリフレッシュする必要があります。)
おそらく、少し実験を行う必要があります。幸いなことに、問題を理解すれば、問題を再現して修正したかどうかをテストするのは非常に簡単です。