nginxの問題解決:上流からの応答ヘッダーの読み込み中に上流が接続を早々に切断した
質問の背景
弊社側は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、たまに報告される不具合を無視してはいけない、後々システムのボトルネックになるかもしれない。
関連
-
[解決済み】Raspberry Piサーバーに対して小規模なDDoS攻撃を実行する【終了しました
-
[解決済み] nginxのエラー "conflicting server name "を無視する [終了しました]。
-
[解決済み] どのヘッダテストツールでもnginxが400 bad request headersを投げるのを修正する方法は?
-
[解決済み] Certbot /.well-known/acme-challenge
-
[解決済み] Nginx 無効なPID番号
-
Gitはいくつかのバグフィックスを行いました。マージされていないファイルがあるため、Pullができない。
-
Nginxエージェントのリソース: net::ERR_NAME_NOT_RESOLVED の読み込みに失敗しました。
-
nginx スタートアップ・エラー。nginx.serviceのジョブは、制御プロセスがエラーコードで終了したため失敗しました。
-
NginxのRequest Entity Too Largeの解決法
-
アップストリームエラーの読み込み中に、アップストリームが接続を早々に切断した
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Docker Nginxが停止しました。[emerg] 1#1: ホストがアップストリームで見つかりません。
-
[解決済み] nginxリクエストで許容されるurlの長さを設定する方法 (エラーコード: 414, uri too large)
-
[解決済み] NGINXを設定して、サブルートで場所(同じサーバー名の下)に応じて異なるシングルページアプリケーション(SPA...すなわち静的ファイル)をデプロイする方法
-
[解決済み] バックグラウンドでリクエストするようにnginxを設定する
-
ブラウザエラー net::ERR_CONTENT_LENGTH_MISMATCH 200 (OK) 解決策
-
linux システムでの Nginx のインストール: make: *** `install' をターゲットとするルールがありません。停止します。
-
OSError: [Errno 98] アドレスはすでに使用中です。
-
Nginx] エラー413 Request Entity Too Largeの解決方法