web-dev-qa-db-ja.com

サーバーがSYNパケットに応答してSYN / ACKパケットを送信しない理由

最近、TCP接続の問題のほとんどが、私たちのWebサイトを閲覧するMacおよびLinuxユーザーに限定されていることに気づきました。

ユーザーの観点から見ると、それは私たちのウェブサイトへの非常に長い接続時間(> 11秒)として現れます。

私たちはこの問題の技術的なシグネチャを追跡することに成功しましたが、それが発生している理由またはそれを修正する方法を理解できません。

基本的に、クライアントのマシンがSYNパケットを送信してTCP接続を確立し、Webサーバーがそれを受信しますが、SYN/ACKパケットで応答しません。は多くのSYNパケットを送信し、サーバーは最終的にSYN/ACKパケットで応答し、接続の残りの部分はすべて正常です。

そしてもちろん、問題へのキッカー:それは断続的であり、常に発生するわけではありません(それは時間の10-30%の間で発生しますが)

OSとしてFedora 12 Linuxを使用し、WebサーバーとしてNginxを使用しています。

Wireshark分析のスクリーンショット

Screenshot of wireshark analysis

更新:

クライアントでウィンドウスケーリングをオフにすると、問題が発生しなくなりました。今、私はサーバー側の解像度が必要です(すべてのクライアントにこれをさせることはできません):)

最終更新:

解決策は、両方のTCPウィンドウスケーリングandTCPタイムスタンプ一般にアクセス可能なサーバー上。

46
codemonkey

これとまったく同じ問題がありました。 TCPタイムスタンプを無効にするだけで問題が解決しました。

sysctl -w net.ipv4.tcp_timestamps=0

この変更を永続的にするには、/etc/sysctl.confにエントリを作成します。

TCPウィンドウスケールオプションを無効にする場合は、十分注意してください。これは、インターネット経由で最大のパフォーマンスを提供するための オプションは重要です です。10メガビット/秒の接続を持つユーザーは、 往復時間 (基本的にはpingと同じ)が55ミリ秒を超える場合、転送は最適ではありません。

同じNATの背後に複数のデバイスがある場合、この問題に本当に気付きました。 AndroidデバイスとOSXマシンからのタイムスタンプを同時に見ると、タイムスタンプフィールドにまったく異なる値が入力されているため、サーバーが混乱しているのではないかと思います。

15
mcdizzle

私の場合、次のコマンドでLinuxサーバーからのSYN/ACK応答がない問題を修正しました。

sysctl -w net.ipv4.tcp_tw_recycle=0

TCPタイムスタンプ、TCPタイムスタンプは ハイパフォーマンス (PAWS、ウィンドウスケーリング、等)。

多くのNATルーターはタイムスタンプを保持するため、同じIPからのタイムスタンプが一貫していないため、PAWSが作動するため、tcp_tw_recycleのドキュメントには有効にすることは推奨されないことが明示されています。

   tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
          Enable fast recycling of TIME_WAIT sockets.  Enabling this
          option is not recommended for devices communicating with the
          general Internet or using NAT (Network Address Translation).
          Since some NAT gateways pass through IP timestamp values, one
          IP can appear to have non-increasing timestamps.  See RFC 1323
          (PAWS), RFC 6191.
12
lav

不思議に思いますが、なぜSYNパケット(フレーム#539;受け入れられたもの)の場合、 "Info"列にWSおよびTSVフィールドがありませんか?

WSはTCPウィンドウスケーリングであり、TSVはタイムスタンプ値です。どちらもtcp.optionsフィールドの下にあり、Wiresharkが存在する場合でも表示する必要があります。クライアントのTCP/IPスタックが8回目の試行で別のSYNパケットを再送信した可能性があり、それが突然確認された理由ですか?

フレーム539の内部値を提供してもらえますか? SYN/ACKは、WSが有効になっていないSYNパケットに対して常に発生しますか?

5
user389238

まったく同じ問題が発生しました(syn-ackを送信せずにサーバーにピン留めするのにかなり時間がかかりました)。

「解決策は、一般にアクセス可能なサーバー上のTCPウィンドウスケーリングとTCPタイムスタンプをオフにすることでした。」

4
Alex Li

SYN/ACKがないのは、ファイアウォールのSYNFLOOD保護の制限が低すぎることが原因である可能性があります。これは、サーバーユーザーが作成する接続の数によって異なります。 spdyを使用すると、接続の数が減り、net.ipv4.tcp_timestamps offは役に立ちません。

2
brablc

Ansisの発言を引き継ぐために、ファイアウォールがTCP Windows Scalingをサポートしていない場合にこのような問題が発生することを確認しました。これらの2つのホスト間にはどのようなmake/modelファイアウォールがありますか?

2
joeqwerty

Linux TCPクライアントが3回の試行後にSYNパケットを変更し、ウィンドウスケーリングオプションを削除したことを発見しました。これがインターネットでの接続障害の一般的な原因であるとカーネル開発者が推測したと思います

それはこれらのクライアントが11秒後に接続を管理する理由を説明します(ウィンドウのないTCP SYNはデフォルト設定の私の簡単なテストで9秒後に発生します)

1

これは、バックログがいっぱいのときのリスニングTCP=ソケットの動作です。

Ngnixでは、バックログ引数が設定でリッスンするのを許可します: http://wiki.nginx.org/HttpCoreModule#listen

80のバックログを聞く=数字

Numをデフォルトよりも大きい値(1024など)に設定してみてください。

完全な待機キューが実際に問題であるという保証はありませんが、最初に確認することをお勧めします。

1
akramer

同様の問題がありましたが、私の場合、TCPチェックサムが誤って計算されました。クライアントはvethの背後にあり、ethtool -K veth0 rx off tx offを実行していたので、うまくいきました。

0
Baroudi Safwen