弊社の Web プロジェクトの 1 つでは、新しい都市の増加によりトラフィックと DB 負荷が増加しています。インターフェイスのビジネス プロバイダーとして、最近、ダウンストリーム フィードバックから大量の「502」リクエストを受け取りました。 502 (Bad Gateway) は、通常、上流 (この場合は PHP) のエラーによって発生します。PHP の場合、502 の一般的な原因は、スクリプトの実行がタイムアウト設定時間を超えたか、タイムアウト設定が大きすぎるために、PHP プロセスが長時間解放できず、クライアントを受信するアイドル ワーカー プロセスがないことです。 私たちのプロジェクトは、PHP の実行時間が短すぎることが原因です。この場合、502 が最初にクリアされるように、PHP の実行時間を適切に増やすことができます。結局、最適化には時間がかかります。 PHP 実行時間を制御するオプションは 2 つあります。php.ini の max_execution_time と php-fpm の request_terminate_timeout です。Request_terminate_timeout は max_execution_time を上書きできるため、グローバル php.ini を変更したくない場合は、php-fpm 構成のみを変更する必要があります。 次に、PHP スクリプトの実行が設定時間を超え、nginx が 502 を返す原因を詳しく分析します。 まず問題を再現するための状況を設定しましょう: Nginx と PHP は、追跡を容易にするためにそれぞれ 1 つのワーカーのみを起動します。 php-fpm の request_terminate_timeout は 3S に設定されています。 テストスクリプト test.php 睡眠(20); 'ok' をエコーします。 行け!行け!行け: ブラウザで www.v.com/test.php にアクセスすると、3 秒後に結果は...404 になりますか? ? ?何? ? ? スタートは良くありません。nginxの設定ファイルを見てみましょう。 この場所の設定は、5xx エラーが発生したときに見栄えの良いインターフェースにジャンプするためのものですが、/usr/share/nginx/html に 50x.html ファイルがありません。それで404エラーが発生しました。これは私の判断の正確さに影響しませんか?コメントアウトするだけです!再度アクセスし、3 秒待つと、最終的に「通常の」インターフェースが表示されます。 環境の準備ができたので、手順に従って、Web の問題のトラブルシューティング ルーチンを実行してみましょう。まず、エラー ログを見てみましょう。 nginx: エラー メッセージはすべて、recv() が失敗しました (104: ピアによって接続がリセットされました)。 受信に失敗し、接続がリセットされました。接続がリセットされたのはなぜですか?意見の相違はありますか? php-fpm のエラー ログを見てみましょう。 (php-fpm の php_admin_value[error_log] オプションは PHP エラー ログを指定し、php.ini のログを上書きすることに注意してください。ただし、ここでは PHP エラーではなく PHP-fpm エラーを調べます。PHP-fpm エラー ログは php-fpm.conf の error_log オプションによって指定されます。) 各リクエストでは 2 つの警告と 1 つの通知が生成されます。 警告: スクリプトの実行がタイムアウトになり終了しました。 警告: 子プロセスは SIGTERM シグナルを受信して終了しました。 注意: 新しい子プロセスが開始されました (pm.min_spare_servers = 1 に設定したため) PHP ワーカー プロセスの実行がタイムアウトすると、スクリプトの実行が終了するだけでなく、ワーカー プロセスも終了するようです。 php ワーカー プロセスが終了したため、nginx エラー接続がリセットされたようです (TCP 接続では、一方の接続が切断されると、もう一方の接続に RST が送信されます) ログから、PHP スクリプトの実行がタイムアウトし、ワーカー子プロセスが終了したため、nginx が「Connection reset by peer」というエラーを報告したことがわかります。次に、strace を使用して PHP と nginx の状況を確認します。 php: 1. nginx の接続要求を受け入れます (socket、bind、listen はすべてマスターで完了します)。nginx のポートが 47039 であることがわかります。FD0、つまり標準入力からデータを読み取ります。これは fast-cgi プロトコルで規定されています。受け入れ後の接続記述子は 3 です。 2. nginx から FD3 に渡されたデータを fastcgi プロトコル形式で読み取り、856 バイトを受信します。なぜ5回読むのですか? fastcgi プロトコル データ パケットは 8 バイト境界に配置され、ヘッダーと本体から構成されるためです。そして、最初にリクエスト ID、バージョン、タイプ、その他の情報を含むリクエスト データ パケットを送信し (ヘッダーと本文はそれぞれ 8 バイトを占めます)、次にパラメータ データ パケットを送信して get パラメータと環境変数を渡し (ヘッダーは 8 バイト、本文の方が長い)、最後にパラメータ送信の終了を示す、本文がなくヘッダーのみのパラメータ データ パケットを送信します (ヘッダーは 8 バイトです)。したがって、最初の 3 つの読み取りは、リクエスト パケットのヘッダーと本文、およびパラメータ パケットのヘッダーを読み取るために使用されます。4 番目の読み取りは実際のデータを読み取るためのもので、最後の読み取りは最後のパラメータ パケットのヘッダーを読み取るためのものです。したがって、nginx によって送信されるデータは 8+8+8+856+8=896 バイト (以下の nginx の送信バイトに相当) になります。 post メソッドが使用される場合、stdin データ パケットも送信されることに注意してください。 3. スリープ時間を20秒に設定します。PHPプログラムではsleep(20)です。プロセスが終了するので、これ以上は発生しません。 strace プログラムも終了します。 nginx: 1.ブラウザへのリクエストを受け入れます。ブラウザ側のポートは56434、IPは192.168.1.105、確立された接続のFDは3であることがわかります。 2. FD3、HTTP プロトコルからデータを受信します。 3. PHP との接続を確立するためのソケット FD21 を作成します。 4. FD21 に接続すると、ローカル マシンのポート 9000 への接続が行われていることがわかります。ここで、nginx と php-fpm は IP ソケット接続方式を使用します。nginx と php-fpm が同じマシンに展開されている場合は、Unix ドメイン ソケットを検討できます。 5. fast-cgi プロトコル形式で FD21 にデータを書き込みます。書き込まれた長さは 896 であり、これは上記の PHP によって受信された長さに対応していることがわかります。 6. recvfrom関数はFD21からECONNRESET(ピアによる接続リセット)を返します。 7. エラー情報を FD9 に書き込みます。FD9 は nginx エラー ログのファイル記述子であると推測できます。 8. FD21との接続を閉じます。 9. ブラウザに返される情報である 502 Bad Gateway を FD3 に書き込みます。 10. アクセス ログを FD8 に書き込みます。FD8 は nginx アクセス ログのファイル記述子であると推測できます。 nginxのアクセスログとエラーログの推論を検証してみましょう。確かにFD8とFD9であり、書き込みモードになっていることがわかります。 次に、このプロセスにおけるネットワーク パケット全体の送信を見てみましょう。 tcpdump を介してパケットをキャプチャし、アーティファクトを使用して表示する方が便利です。 nginx と php 間の通信のみを確認したいのですが、nginx のポートが 47039 であることがわかっているので、tcp.srcport==47039 を介して対応するパケットをフィルタリングできます。 nginx と php-fpm 間のデータ相互作用プロセスを確認できます。47039->9000 は 3 ウェイ ハンドシェイクを確立し、次に 9000 にデータを送信し、9000 は ACK を応答し、9000 は 3 秒後に RST を応答します。何も問題はありません。 知らせ: SYNとFINはそれぞれシーケンス番号を占有する ACK と RST はシーケンス番号を占有しません (パケット 28 と 29 の reqnum と acknum は同じです) シーケンス番号はバイトごとに 1 です (パケット 29 は 896 バイトを送信し、パケット 29 のシーケンスは 4219146879 で、パケット 30 の ack は 4219147775 であり、正確に 896 バイト異なります) RST は応答を必要としません。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Windows 上の MySQL 5.6 で my.ini 設定ファイルを見つける方法
目次ZabbixはNginxを監視するZabbixはTomcatを監視するZabbixはMySQLを...
コードをコピーコードは次のとおりです。 @文字セット "utf-8"; /* @...
Windows 2003+IIS6 の fastcgi 構成ファイル fcgiext.ini を最適...
目次導入インストール1. マウントするフォルダを作成する2. イメージをプルする3. コンテナを作成...
以下のコマンドのほとんどは、コンソール/ターミナル/シェルで入力する必要があります。 'su...
まず、この投稿は Docker 初心者向けです。もちろん、ベテランであれば記事中の分割線以降の操作方...
目次G2チャートについて使用テンプレートで使用される完全なコード (棒グラフ)世界地図を追加するG2...
1. MySQLをダウンロードするURL: https://dev.mysql.com/downlo...
今日、vue3+viteプロジェクトの実践で、svgを使用する場合、以前の記述方法が使用できないこと...
目次vuex 永続性要約するvuex 永続性vuex: ブラウザを更新すると、vuexの状態は初期状...
目次レンダリングインストールコードの実装カスタムスタイル要約する効率的に要件を満たし、車輪の再発明を...
目次シンプルなSpringbootプロジェクトを作成する1. pom.xmlでSpring Boot...
メインのオペレーティング システムを Windows から Ubuntu に切り替えたとき、最初に考...
目次1. 終了2. クロージャの使用シナリオ1.タイムアウトを設定する2. コールバック3. 手ぶれ...
フレックスレイアウト定義: Flexレイアウトの要素は、 Flex 、または略して「コンテナー」と呼...