1. ホーム
  2. nginx

nginxの問題解決:上流からの応答ヘッダーの読み込み中に上流が接続を早々に切断した

2022-02-19 15:09:39
<パス

質問の背景

弊社側はNginxベースのAPIゲートウェイ(下記Aと表記)なのですが、ここ2日ほど呼び出し元から「たまに502エラーが出る」というフィードバックがあり、Nginxのエラーログを見てみると、" upstream prematurely closed connection while reading response header from upstream" というエラーログがあって、実際には上流サービスが早々に接続を閉じていると翻訳されていて、意味は明確ですがなぜこんなことが起こるんでしょうか。そして、低ピークのビジネスでこのような状況が表示されます(また、発生のわずかな確率)、ビジネスのピーク時にこのような状況が表示されませんでした、上流のサービス(以下Bとしてマーク)は、彼らが受信しなかった要求の問題は、つまり、むしろ奇妙であるレコードがありませんと言いました。テスト環境では再現方法がわからず、トラブルシューティングに不利な状況です。

トラブルシューティングの流れ

1、パケットをつかむために、サーバー上のtcpdumpをオンにする tcpdump -nps0 -iany -w /tmp/20180617.pcap net [ip] とnet [ip], あなたはtcpdumpを使用する方法がわからない場合学生はそれをBaiduできます.

  2、nginx の error.log で、以下のように 2 つの " upstream prematurely closed connection while reading response header from upstream" エラーログがそれぞれ 2018/06/07 20:41:27 と 2018/06/08 09:10:46 に観測されました。

3、次にパケットキャプチャデータを確認し、時点に対応するパケットデータを見つけ、これからわかることは、AがBに1060-2143パケットを送信し、サーバーはFin切断を送信したことです。なぜサーバー側が切断したのか、それはわかりません。

4. でAが送信したパケットの1バイト目は1060だったので、それ以前にパケットを送信しているはずであり、その後も上方確認を行ったところ、以下に示すような現象が確認されました。20時40分22秒に3ハンドシェイクで接続を確立し、最初のパケットを送信した。また、20時40分22秒から20時41分27秒の間に、この長い接続がパケットを送信していないことを確認した。

5. Bさんに話を聞くと、Nginxのkeepalive_timeoutの設定を65秒にしているそうです。keepalive_timeoutの設定は、長い接続を一定時間維持し、それ以上データ転送がない場合はサーバーが接続を終了することを意味します。つまり、その通り、65秒間データ転送がなく、まさにその時点でAがBにデータを送り、Bがコネクションを閉じてしまい、上記の現象が発生したということです。

6. もちろんこれはパケットキャプチャ解析による結果であり、私自身も1分ごとに1番目のnginxにリクエストを送り、2番目のnginxに転送する時限タスクを書いてこの状況をシミュレートしました。2 番目の nginx の keepalive_timeout は 60 に設定し、7 回目を送信したところ、同じ問題が発生し、nginx は同じエラーログを出力し、パケットキャプチャの結果も上記の状況と一致しました。上記の私の解析プロセスを検証しています。

問題の概要

1、システムの同時性が大きくない場合、長い接続を開く必要がない、2つの方法があります、1、最初のnginxは、proxy_http_version 1.1; proxy_set_header Connection "0" この二つの設定を削除できます、2、第2のnginxのキープアライブ_タイムアウトは0(デフォルトは75)に設定することができます。

2. 上記の問題に対する私の解決策は、まずkeepalive_timeoutの値を一時的に上方修正して観察することですが、それでも問題が発生する可能性が高いようです。

追記

1. ネットワーク問題のトラブルシューティングのプロセスが苦痛になり、改めて基礎の重要性を検証しました。

2、たまに報告される不具合を無視してはいけない、後々システムのボトルネックになるかもしれない。