502 Bad Gateway - ソケットのハングアップ

Apigee Edge のドキュメントを表示しています。
Apigee X のドキュメントに移動します。
情報

症状

クライアント アプリケーションが、Edge Microgateway での API 呼び出しに対するレスポンスとして、HTTP ステータス コード 502 Bad Gateway とコード ECONNRESET を受け取ります。

エラー メッセージ

クライアントには次のレスポンス コードが表示されます。

HTTP/1.1 502 Bad Gateway

レスポンスには次のエラー メッセージが含まれます。

{"message":"socket hang up","code":"ECONNRESET"}

考えられる原因

原因 説明 トラブルシューティングの実施対象
keep-alive タイムアウトが正しく構成されていない Edge Microgateway とターゲット サーバーの間で keep-alive タイムアウトが正しく構成されていない。 Edge Public Cloud と Private Cloud のユーザー
ターゲット サーバーが接続を早期に閉じる Edge Microgateway がリクエスト ペイロードを送信している間に、ターゲット サーバーが接続を早期に閉じます。 Edge Public Cloud と Private Cloud のユーザー

共通の診断手順

  1. Edge Microgateway のログを確認します。
    /var/tmp/edgemicro-`hostname`-*.log
  2. 特定の期間にコード ECONNRESET502 エラーが発生したかどうか(問題が過去に発生した場合)、または 502 でリクエストがまだ失敗しているかどうかを検索します。
    2021-06-23T03:52:24.110Z [error][0:8000][3][myorg][test]
    [emg_badtarget/flakey/hangup][][][6b089a00-d3d6-11eb-95aa-911f1ee6c684]
    [microgateway-core][][GET][502][socket hang up][ECONNRESET][]
  3. ロギングレベルが warn または info に設定されている場合は、2 番目の要素にターゲット サーバーのホスト名とポートを含む [warn] メッセージも表示されます。この例では X.X.X.X:8080 です。これは後で tcpdump をキャプチャするために使用できます。
    2021-06-23T03:52:24.109Z
    [warn][X.X.X.X:8080][3][myorg][test][emg_badtarget/flakey/hangup]
    [][][6b089a00-d3d6-11eb-95aa-911f1ee6c684][plugins-middleware]
    [targetRequest error][GET][][socket hang up][ECONNRESET][395]
  4. エラーコード [socket hang up][ECONNRESET] は、ターゲット サーバーが Edge Microgateway との接続を閉じたことを示します。これはログで検索して、発生頻度を確認できます。

原因: keep-alive タイムアウトが正しく構成されていない

診断

  1. 共通の診断手順の手順に沿って、[socket hang up][ECONNRESET] エラーが発生したかどうかを確認します。
  2. 「はい」の場合は、以下で説明する tcpdump を使用してさらに調査します。

tcpdump の使用

  1. 次のコマンドを使用して、Edge Microgateway ホスト オペレーティング システムで Edge Microgateway とバックエンド サーバー間の tcpdump をキャプチャします。
    tcpdump -i any -s 0 host TARGET_SERVER_HOSTNAME -w FILENAME.pcap
    
  2. キャプチャされた tcpdump を分析します。

    tcpdump の出力例: 大きい画像を表示

    上記のサンプル tcpdump では、次のようになっています。

    1. パケット 250288 で、クライアントは POST リクエストを送信します。
    2. パケット 250371 で、サーバーは 200 OK で応答します。
    3. パケット 250559 で、クライアントは ACK. を送信します。
    4. パケット 250560 で、サーバーは Continuation メッセージを送信します。
    5. パケット 250561 で、クライアントが ACK. を送信します。
    6. パケット 262436 で、サーバーは接続の終了を開始するクライアントに FIN, ACK を送信します。これは、前のパケット(250561)から約 5 秒後です。
    7. パケット 262441 で、クライアントは別の POST リクエストを送信します。ただし、サーバーがすでに接続の終了を開始しているため、これは失敗します。パケット 262441RST を返します。

    この例では、同じ接続が少なくとも 1 回は正常に再利用されていますが、最後のリクエストでは、サーバーが 5 秒間のアイドル時間の後に接続の終了を開始します。これは、クライアントが新しいリクエストを送信したタイミングと一致しています。これは、バックエンド サーバーのキープアライブ タイムアウトが、クライアントで設定された値以下である可能性が高いことを示しています。これを確認するには、Edge Microgateway とバックエンド サーバーのキープアライブ タイムアウトを比較するをご覧ください。

Keep-alive タイムアウトを比較する

  1. Edge Microgateway には、特定のキープアライブ タイムアウト プロパティはありません。これは、実行されているオペレーティング システムによって決まります。一般的な例としては、Windows、Linux、Docker コンテナなどがあります。
  2. オペレーティング システムでカスタマイズされている可能性があります。システム管理者にお問い合わせください。デフォルトでは、Linux オペレーティング システムのデフォルトのキープアライブ タイムアウトは 2 時間です。
  3. 次に、バックエンド サーバーで構成されているキープアライブ タイムアウト プロパティを確認します。バックエンド サーバーが 10 秒の値で構成されているとします。
  4. オペレーティング システムのキープアライブ タイムアウトの値が、上記の例のようにバックエンド サーバーのキープアライブ タイムアウト プロパティの値よりも大きい場合は、それが 502 エラーの原因です。

解決策

Edge Microgateway が実行されているオペレーティング システムの keep-alive タイムアウト プロパティが、バックエンド サーバーのタイムアウト プロパティよりも常に小さくなるようにします。

  1. バックエンド サーバーで設定されている keep-alive タイムアウトの値を特定します。
  2. オペレーティング システムで、keep-alive タイムアウト プロパティがバックエンド サーバーに設定された値よりも小さくなるように、keep-alive タイムアウト プロパティに適切な値を構成します。オペレーティング システムに適用可能な手順を使用します。

ベスト プラクティス

このような競合状態と 502 エラーを回避するため、ダウンストリーム コンポーネントのキープアライブ タイムアウトしきい値は、アップストリーム サーバーで構成された値よりも常に小さくすることをおすすめします。各ダウンストリーム ホップは、各アップストリーム ホップよりも小さくする必要があります。Edge Microgateway では、次のガイドラインを使用することをおすすめします。

  1. クライアント アプリケーションまたはロードバランサのキープアライブ タイムアウトは、Edge Microgateway のキープアライブ タイムアウトよりも短くする必要があります。

    Edge Microgateway で keep-alive タイムアウトを構成するには、~/.edgemicro/org-env-config.yaml ファイルに keep_alive_timeout 値を追加します。

    edgemicro:
      keep_alive_timeout: 65000
  2. Edge Microgateway のオペレーティング システムのキープアライブ タイムアウトは、ターゲット サーバーのキープアライブ タイムアウトよりも短くする必要があります。
  3. Edge Microgateway の前後に他のホップがある場合は、同じルールを適用する必要があります。アップストリームとの接続を閉じるのは、常にダウンストリーム クライアントの責任としてください。

原因: ターゲット サーバーが接続を早期に閉じる

診断

  1. 共通の診断手順で説明されている手順に沿って、[socket hang up][ECONNRESET] エラーが発生したかどうかを確認します。
  2. 「はい」の場合は、以下で説明するように tcpdump を使用してさらに調査します。

    上記の例のエラー メッセージ [targetRequest error][GET][][socket hang up][ECONNRESET] は、Edge Microgateway がバックエンド(ターゲット)サーバーにリクエストを送信しているときにこのエラーが発生したことを示しています。つまり、Edge Microgateway は API リクエストをバックエンド サーバーに送信し、レスポンスを待機していました。しかし、バックエンド サーバーは、Edge Microgateway がレスポンスを受け取る前に、突然接続を終了しました。

  3. バックエンド サーバーのログを確認し、バックエンド サーバーの突然の接続終了を引き起こした可能性のあるエラーや情報がないかどうかを確認します。エラーや情報が見つかった場合は、解決策に進み、バックエンド サーバーで問題を適切に修正します。
  4. バックエンド サーバーでエラーや情報が見つからない場合は、Edge Microgateway サーバーで tcpdump の出力を収集します。
    tcpdump -i any -s 0 host TARGET_SERVER_HOSTNAME -w FILENAME.pcap
    
  5. キャプチャされた tcpdump を分析します。

    tcpdump の出力例: 大きい画像を表示

    上記のサンプル tcpdump では、次のようになっています。

    1. パケット 4 で、Edge Microgateway はターゲット サーバーに GET リクエストを送信しました。
    2. パケット 5 で、ターゲット サーバーは ACK で応答してリクエストを確認しました。
    3. ただし、パケット 6 では、ターゲット サーバーはレスポンス ペイロードで応答する代わりに、接続の終了を開始する FIN, ACK を送信します。
    4. パケット 7 以降では、接続は相互に閉じられます。レスポンスが送信される前に接続が閉じられたため、Edge Microgateway は HTTP 502 エラーをクライアントに返します。
    5. パケット 8 のタイムスタンプ 2021-06-23T03:52:24.110Z は、Edge Microgateway ログにエラーが記録されたタイムスタンプに対応しています。ログファイルと tcpdump のタイムスタンプは、エラーと実際のパケットを関連付けるために使用できます。

    解決策

    バックエンド サーバーの問題を適切に修正します。

    問題が解決せず、502 Bad Gateway Error のトラブルシューティングのサポートが必要な場合、または Edge Microgateway 内の問題であることが疑われる場合は、診断情報の収集が必要な場合に進みます。

    診断情報の収集が必要な場合

    上記の手順でも問題が解決しない場合は、次の診断情報を収集して Apigee Edge サポートにお問い合わせください。

    • ログファイル: デフォルトのフォルダは /var/tmp ですが、メインの config.yaml ファイル(logging > dir parameter)でオーバーライドされることがあります。Apigee サポートにログファイルを提供する前に、log > levelinfo に変更することをおすすめします。
    • 構成ファイル: Edge Microgateway のメイン構成は、デフォルトの Edge Microgateway フォルダ $HOME/.edgemicro の YAML ファイルにあります。デフォルトの構成ファイル default.yaml と、環境ごとの構成ファイル ORG-ENV-config.yaml があります。影響を受ける組織と環境について、このファイルをすべてアップロードしてください。