TCP HTTPトラフィックのポートの再利用と再送信による問題に直面しています。
私の展開は次のとおりです:
信頼できるソースからのHTTP要求の処理を送信しているUNIXマシンにSquidプロキシがインストールされています。 Squidは、ホワイトリストとブラックリストのリストを持つURLフィルターに転送します。ルールに従ってURLを許可/ブロックするこのURLフィルタリングエンジン。
クライアントから、www.naukri.comへの500 wgetをループで継続的に実行するスクリプトを実行しました。このURLは、URLフィルタリングエンジンでブロックしています。
いくつかの要求の後、120 wgetがちょうど1分間ハングしました。このハング状態の間に、サーバーでtcpdumpを実行したところ、「再利用されたTCPポート番号」が表示され、以前に使用されたのと同じポートで同期パケットの送信を開始し、「TCP再送信」が表示されました。また、前の要求に対して受信されたFIN、ACK、およびRST。
参照用にtcpダンプのスクリーンショットを添付:
新しいリクエストに同じポートを使用し、パケットを再送信する理由を教えてください。ポートの再利用を回避する方法はありますか?
新しいリクエストに同じポートを使用し、パケットを再送信するのはなぜですか?
同じポートを再利用する方が効率的であるためです。
ここに良い説明があります: https://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean- t
再送信しますか?何を再送信しますか?パケットの再送信が発生する可能性がありますが、これらはポートの再利用の問題とは完全に分離する必要があります。
同様の問題が発生しました。 (httpdではなくlockd
を使用)。
ここでの問題は、リモートサーバーがFINパケットで接続を閉じたサーバーであることです。
これを行うと、接続がTIME_WAIT
状態になります。これは、追加のフラグメントがまだ飛行中または別のネットワークルートに移動している場合に備えて、追加のパケットをすべて無視することになっています。
そのため、サーバーでTIME_WAIT
が期限切れになるまで、アプリケーションから送信された追加パケットは無視されます。
クライアントはこれらのパケットのACK
を取得しないため、再送信します。 (TIME_WAIT
が期限切れになるまで、これも無視されます。
なぜFINパケットを送信したのですか?言いにくい。それはサーバー次第です。しかし、サービス拒否攻撃のように見えた場合は、それが理由かもしれません。
ただし、実際にクライアントのCLOSE_WAIT
状態をトラップし、notが発生した場合は、ソケットを再利用する必要があります。
TCPポートを再利用すること自体は悪いことではありません。symcbeanが指摘したように、より効率的であり、多くの新しいソケットをすばやく開くため、例ではそれが明らかである場合があります。キャプチャのスクリーンショットを見ると、プロセスを開始してから2秒が経過しており、約120の接続後にスタックするという話がありました。これは、2秒での新しい接続の数として十分です。
表示されている再送信は、ネットワーク内の他の誰かがあなたから他のSYNパケットをドロップしたことが原因である可能性があります。同じホストからの毎秒60の新しい接続は、ほとんどすべてのネットワークおよびセキュリティ管理者にとって有害であると見なされ、ファイアウォールまたはプロキシのデフォルト設定がトラフィックを静かにドロップし始めます。
ユーザー負荷をシミュレートしようとしている場合は、正しく実行していないと思います。複数の異なるホストからの毎秒60の新しい接続はOKですが、それらが単一のホストからのものである場合は非現実的です。実際、ユーザーのブラウザは、単一のホストへの接続を6〜12の同時数に制限します(ブラウザとバージョンによって異なります)。一部のブラウザーは、プロキシーを単一のホストと見なしますが、他のブラウザーでは、プロキシーに対して異なる制限があります(同時に15まで)。
設定を微調整することでSquidの制限を回避できますが、それでも非現実的なテストです。