Nginxエラーログを分析して接続拒否をトラブルシューティングする

Nginxの接続拒否エラーをログから正確なアップストリームサービス、ポート、ソケット、またはネットワークの問題にトレースする方法を学びます。

Nginxエラーログを分析して接続拒否をトラブルシューティングする

Nginxエラーログを分析して接続拒否をトラブルシューティングすることで、一般的な502ページから特定のバックエンド障害に移行できます。「接続拒否」というフレーズは、通常、Nginxがアップストリームアドレスに接続しようとしたが、どのプロセスも接続を受け入れなかったことを意味します。

これはタイムアウト、DNS障害、または不正な応答とは異なります。ログパターンを認識すれば、修正を迅速に絞り込むことができます。

「接続拒否」の意味

Nginxログでは、次のような一般的なメッセージが表示されます:

connect() failed (111: Connection refused) while connecting to upstream

これは、オペレーティングシステムが接続試行を拒否したことを意味します。Nginxはターゲットホストに到達しましたが、ターゲットポートでリッスンしているものがないか、接続が積極的に拒否されました。

Nginxが次のようにプロキシするときに表示されることがあります:

proxy_pass http://127.0.0.1:3000;

しかし、アプリケーションが停止しているか、別のポートでリッスンしています。

このエラーはデプロイ後によく発生します。プロセスマネージャーがアプリの再起動に失敗したり、コンテナがクラッシュしたり、新しい設定がNginxを更新せずにアプリのポートを変更したりする可能性があります。

すべての502を接続拒否として扱わないでください。タイムアウトメッセージは別の方向を示しています。アクセス拒否メッセージは、多くの場合、ソケットやセキュリティポリシーを指します。正確なログテキストが重要です。

適切なNginxエラーログを見つける

デフォルトのエラーログパスは、多くの場合次のとおりです:

/var/log/nginx/error.log

ただし、サーバーブロックはカスタムログを定義できます:

error_log /var/log/nginx/app-error.log warn;

デフォルトのログに最近のエントリが表示されない場合は、関連するNginx設定を確認してください。一部のシステムでは、サービスレベルのメッセージがシステムジャーナルにも表示されます。

便利なコマンドは次のとおりです:

tail -n 100 /var/log/nginx/error.log

および:

journalctl -u nginx -n 100

テストするときは、ブラウザまたはcurlで1つのリクエストをトリガーし、すぐに最新のログ行を確認してください。これにより、ユーザー向けのエラーとバックエンドの障害を関連付けるのがはるかに簡単になります。

適切なログレビューでは、次の4つの情報を取得します:

  • 失敗したリクエストのタイムスタンプ。
  • アップストリームアドレスとポート。
  • リクエストパス。
  • 111: Connection refusedなどの正確なシステムエラー。

より広範なNginxトラブルシューティングについては、Nginx 502 Bad Gatewayエラーの修正を参照してください。

ログエントリをアップストリームにマッピングする

典型的なログ行には、次のようなアップストリーム値が含まれる場合があります:

upstream: "http://127.0.0.1:3000/api/status"

これは、Nginxがリクエストを送信しようとした正確な場所を示しています。次に、そこにリッスンしているものがあるかどうかを確認します:

ss -ltnp

127.0.0.1:30000.0.0.0:3000、または予想されるアドレスを探します。ポートが見つからない場合、アプリはNginxが期待する場所でリッスンしていません。

アップストリームを直接テストします:

curl -i http://127.0.0.1:3000/api/status

これが接続拒否で失敗した場合、Nginxを介さずに問題を確認できました。

アプリがDockerで実行されている場合、127.0.0.1に注意してください。ホストからは、ホストを意味します。Nginxコンテナ内からは、Nginxコンテナ自体を意味します。Composeセットアップでは、Nginxは通常、次のようにサービス名にプロキシする必要があります:

proxy_pass http://app:3000;

両方のコンテナが同じDockerネットワークを共有している場合に限ります。

Unixソケットの場合、ログはポートではなくパスを指す場合があります:

upstream: "http://unix:/run/app/app.sock:/"

その場合、ソケットが存在するかどうか、およびNginxワーカーユーザーがアクセスできるかどうかを確認します。

一般的な原因と修正

最も一般的な原因は、停止したバックエンドサービスです。次のコマンドで確認します:

systemctl status your-app

失敗した場合は、再起動する前にアプリのログを読んでください。再起動するとサイトが復元される可能性がありますが、ログは失敗の理由を説明します。

もう1つの一般的な原因は、ポートの不一致です。たとえば、アプリがポート3000から8080に変更されたが、Nginxがまだ3000にプロキシしている場合です。Nginxのアップストリームターゲットを修正するか、アプリの期待されるポートを復元します。

3番目の原因は、間違ったインターフェースへのバインドです。127.0.0.1のみでリッスンするアプリは、同じホスト上のローカルNginxから到達可能です。ただし、Nginxが別のコンテナまたは別のサーバーで実行されている場合、そのループバックアドレスを介して到達できません。これらの設定では、アプリはプライベートネットワーク内の0.0.0.0にバインドする必要がある場合があります。

ファイアウォールルールも接続を拒否または拒絶する可能性があり、特にサーバー間で発生します。Nginxが別のホストにプロキシする場合、アップストリームポートがNginxマシンから開いていることを確認してください。自分のラップトップからのみではありません。

最後に、デプロイのタイミングにより、一時的な接続拒否エラーが発生する可能性があります。新しいアプリプロセスが準備できる前にNginxがトラフィックを送信すると、ユーザーは断続的な502を目にする可能性があります。ヘルスチェック、 readiness probe、またはグレースフルリスタート戦略でこれを防ぐことができます。

実用的なトラブルシューティングフロー

ログに接続拒否が表示された場合は、次の順序を使用します:

  1. Nginxエラーログからアップストリームホストとポートをコピーします。
  2. Nginxサーバーからその正確なアップストリームにcurlを実行します。
  3. ss -ltnpを実行して、プロセスがリッスンしていることを確認します。
  4. バックエンドサービスのステータスとアプリケーションログを確認します。
  5. Nginxのproxy_pass値をアプリの実際のバインドアドレスと比較します。
  6. 設定が正しく、nginx -tが成功した後にのみNginxをリロードします。

このフローは、アプリが単にダウンしているときにNginxを編集するという一般的な間違いを防ぎます。また、Nginxが間違った場所を指しているときにアプリを繰り返し再起動するという逆の間違いも防ぎます。

コマンドの基本については、Nginxログ監視コマンドを参照してください。

専門家に相談するタイミング

接続拒否エラーが負荷時、複数のアップストリーム間、またはローリングデプロイ中にのみ発生する場合は、助けを求めてください。これらのケースには、プロセス監視、コンテナネットワーキング、ロードバランサーヘルスチェック、または容量制限が関係している可能性があります。

また、アップストリームが本番の支払い、認証、または顧客向けAPIサービスである場合もエスカレーションする必要があります。迅速な復旧が重要ですが、ログを保存し、障害を理解することも重要です。

接続拒否は、注意深く読めば、より明確なNginxエラーの1つです。ログでアップストリームを見つけ、そのターゲットを直接テストし、Nginxの接続を妨げるサービス、ポート、インターフェース、またはネットワークパスを修正してください。ログはすでに出発点を提供しています。