プロキシサーバーから散発的な502が返されます。パケットフローを調べると、nginxがPOSTリクエストをソケットに送信しており、Originサーバーがすでに[FIN、ACK]を送信している)リクエストを確認しています。それはオリジン(応答を送信してから5秒後にのみFIN、ACKを送信します)またはプロキシの問題ですか?
私の理解:
質問:
私はオリジンを所有していないので、そこでキャプチャすることはできません。
追加の詳細:
プロキシのエラーログ(nginxエラーログ):
2017/04/17 06:51:07 [error] 123091#0: *225010841 upstream prematurely closed connection while reading response header from upstream, client: X.90.10, server: www.example.com, request: "POST /web/?a=b HTTP/1.1", upstream: "http://X.32.238:80/web/?a=b", Host: "www.example.com"
このスクリーンショットでは、最後のリクエストのSEQ番号とACK番号が示されています。
この場合の考えられる説明は何ですか?
オリジンの約5秒のアイドルカウンターと、さまざまなクライアント側のアクティビティの間の競合状態。 3番目に関係する変数は、もちろんネットワーク遅延です。
Originには〜5秒のアイドルタイマーがあるようですが、クライアントがNginxプロキシ経由で2番目のリクエスト(POST)を行うのに〜5秒かかります。前者が後者よりも長い場合(ネットワーク遅延を含む)、問題はありません。クライアントリクエストが送信されるまでに少し時間がかかる場合は、問題があります。
POSTとNginxからのFIN、ACKの両方がどのようにほぼ一緒に送信されるかを確認できます:OriginのFIN、ACKのそれぞれ2.4msと2.6ms後。これはあなたを先延ばしにする可能性がありますPOSTは、OriginのFIN、ACKに対する応答です。OriginのFIN、ACKの2.4ms後に送信されるため、ここで追跡します。
プロキシ(nginx)がすでにFINを受信し、実際にそれを確認しているのに、なぜ別のリクエストを送信するのですか? (POST [PSH、ACK]パケットのACK番号は、実際には[FIN、ACK]のSEQ_NUMBER + 1であるため、ファントムビットFINを確認しています。
POSTパケットのACK番号は、おそらく「200 OK」パケット用です。そのHTTP応答の後にサーバー側から来る余分なデータはないため、クライアントからのACKはすべてACKします同じ数。
更新:POSTパケットのACK番号が1増加していることがわかったので、Nginxは[ FIN、ACK]。さらに調査すると、これは問題ないことがわかります。マシンは、送信する予定だったリモート側からの応答を受信した後、接続を続行する予定がない場合、要求を送信して[FIN、ACK]で終了する場合があります。データを要求し、[FIN、ACK]プロセスを続行して終了しました。
これは、Originがアイドル状態の5秒後に接続を閉じることを決定したため、POST直後に来るパケット(およびRSTを送り返すことさえ) -ただし、このRSTが送信されたかどうかは不明です)。
Originがすぐにではなく5秒後にのみ[FIN、ACK]を返す可能性のある理由は何ですか?読み取りタイムアウト/アイドルタイムアウト?
特にHTTP 1.1と永続的な接続の導入以来、FIN、ACKをすぐに返す必要はありません。これらの約5秒は、Originのアイドルタイマーのようです。
両方のことがここで確認されています: https://en.wikipedia.org/wiki/HTTP_persistent_connection -Apache2.2以降のデフォルトの5秒のアイドルタイムアウトを含みます。
推奨されるソリューション
インフラストラクチャについての知識がなければ、実際にソリューションを提案することはできませんが、大まかに言うと、いくつかのオプションがあります。
お役に立てれば :)
これは、アップストリームサーバーのソケットキープアライブタイムアウトが原因であると思います。ソケットは閉じられ、デフォルトのsocket.setsolingerは開きません。
Nginxアップストリームサーバーのキープアライブタイムアウトを許可できると思います。別の作成者が解決しました。 this を参照してください。