503 Service Unavailable - バックエンド サーバーによる早期終了

ここに表示されているのは Apigee Edge のドキュメントです。
Go to the Apigee X のドキュメントに移動します
info

症状

クライアント アプリケーションが、API プロキシの呼び出しの後に、メッセージ Service Unavailable 付きの HTTP レスポンス ステータス 503 を受け取ります。

エラー メッセージ

クライアント アプリケーションは、次のレスポンス コードを受け取ります。

HTTP/1.1 503 Service Unavailable

さらに、次のエラー メッセージも確認できます。

{
   "fault": {
      "faultstring": "The Service is temporarily unavailable",
      "detail": {
           "errorcode": "messaging.adaptors.http.flow.ServiceUnavailable"
       }
    }
}

考えられる原因

原因 説明 トラブルシューティングの実施対象
ターゲット サーバーが接続を早期に閉じる Message Processor がリクエスト ペイロードを送信している間に、ターゲット サーバーが接続を早期に終了します。 Edge Public Cloud と Private Cloud のユーザー

共通の診断手順

失敗したリクエストのメッセージ ID を特定する

Trace ツール

Trace ツールを使用して、失敗したリクエストのメッセージ ID を特定するには:

  1. 問題が引き続き発生する場合は、影響を受けている API に対して トレース セッションを有効にします。
  2. API 呼び出しを行い、503 Service Unavailable エラーコード messaging.adaptors.http.flow.ServiceUnavailable. の問題を再現します。
  3. 失敗したリクエストのいずれかを選択します。
  4. [AX phase] に移動し、次の図に示すように [Phase Details] セクションを下にスクロールして、リクエストのメッセージ ID(X-Apigee.Message-ID)を特定します。

    [Phase Details] セクションのメッセージ ID

NGINX アクセスログ

NGINX アクセスログを使用して、失敗したリクエストのメッセージ ID を特定するには:

NGINX アクセスログを参照して、503 エラーのメッセージ ID を特定することもできます。 これは、過去に発生した問題の場合、または問題が断続的に発生し、UI でトレースをキャプチャできない場合に便利です。 以下の手順に従って、NGINX のアクセスログから発生元を特定します。

  1. NGINX アクセスログ(/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log)を確認します。
  2. 特定の期間(過去に問題が発生した場合)に特定の API プロキシに対して 503 エラーがあるかどうか、または 503 で失敗しているリクエストがまだあるかどうかを検索します。
  3. X-Apigee-fault-code messaging.adaptors.http.flow.ServiceUnavailable503 エラーが発生している場合は、次の例に示すように、1 つ以上のリクエストのメッセージ ID をメモします。

    エラーを示すサンプル エントリ503

    ステータス コード、メッセージ ID、障害発生元、障害コードを示すエントリの例

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

診断

  1. Public Cloud または Private Cloud ユーザーの場合:
    1. Trace ツール(共通の診断手順で説明)を使用して、[Analytics Data Recorded] ペインに次の両方が設定されていることを確認します。
      • X-Apigee.fault-code: messaging.adaptors.http.flow.ServiceUnavailable
      • X-Apigee.fault-source: target

      alt_text

    2. Trace ツール(共通の診断手順で説明) を使用して、`TARGET_REQ_FLOW` TARGET_REQ_FLOW state プロパティの直後の [Error] ペインに次の両方が設定されていることを確認します。
      • error.class: com.apigee.errors.http.server.ServiceUnavailableException
      • error.cause: Broken pipe

      alt_text

    3. 詳細な調査を行うには、tcpdump を使用するに移動します。
  2. Private Cloud ユーザーの場合:
    • 失敗したリクエストのメッセージ ID を特定します。
    • Message Processor ログ (/opt/apigee/var/log/edge-message-processor/logs/system.log)でメッセージ ID を検索します。
    • 次のいずれかの例外が表示されます。

      例外 1: java.io.IOException: Broken pipe occurred while writing to channel ClientOutputChannel

      2021-01-30 15:31:14,693 org:anotherorg env:prod api:myproxy
      rev:1 messageid:myorg-opdk-test-1-30312-13747-1  NIOThread@1
      INFO  HTTP.SERVICE - ExceptionHandler.handleException() :
      Exception java.io.IOException: Broken pipe occurred while writing to channel
      ClientOutputChannel(ClientChannel[Connected:
      Remote:IP:PORT Local:0.0.0.0:42828]@8380 useCount=1
      bytesRead=0 bytesWritten=76295 age=2012ms  lastIO=2ms  isOpen=false)

      または

      例外 2: onExceptionWrite exception: {}
      java.io.IOException: Broken pipe

      2021-01-31 15:29:37,438 org:anotherorg env:prod api:503-test
      rev:1 messageid:leonyoung-opdk-test-1-18604-13978-1
      NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context$2.onException() :
      ClientChannel[Connected: Remote:IP:PORT
      Local:0.0.0.0:57880]@8569 useCount=1 bytesRead=0 bytesWritten=76295 age=3180ms  lastIO=2
      ms  isOpen=false.onExceptionWrite exception: {}
      java.io.IOException: Broken pipe
    • これらの例外はどちらも、Message Processor がリクエスト ペイロードをバックエンド サーバーに書き込んでいる間に、バックエンド サーバーによって接続が早期に閉じられたことを示しています。そのため、Message Processor は例外 java.io.IOException: Broken pipe をスローします。
    • Remote:IP:PORT は、解決されたバックエンド サーバーの IP アドレスとポート番号を示します。
    • 上記のエラー メッセージの属性 bytesWritten=76295 は、接続が早期に閉じられたときに Message Processor が 76295 バイトのペイロードをバックエンド サーバーに送信したことを示しています。
    • 属性 bytesRead=0 は、Message Processor がバックエンド サーバーからデータ(レスポンス)を受信していないことを示しています。
    • この問題をさらに調査するには、バックエンド サーバーまたは Message Processor で tcpdump を収集し、以下で説明するように分析します。

tcpdump を使用する

  1. 次のコマンドを使用して、バックエンド サーバーまたは Message Processor で tcpdump をキャプチャします。

    バックエンド サーバーで tcpdump を収集するコマンド:

    tcpdump -i any -s 0 host MP_IP_ADDRESS -w FILE_NAME
    

    Message Processor で tcpdump を収集するコマンド:

    tcpdump -i any -s 0 host BACKEND_HOSTNAME -w FILE_NAME
    
  2. キャプチャした tcpdump を分析します。

    tcpdump の出力例(Message Processor で収集):

    alt_text

    上記の tcpdump では、次のことがわかります。

    1. パケット 4 で、Message Processor がバックエンド サーバーに POST リクエストを送信しました。
    2. パケット 58 91011 で、Message Processor はリクエスト ペイロードをバックエンド サーバーに送信し続けました。
    3. パケット 67 で、バックエンド サーバーは ACK で Message Processor から受信したリクエスト ペイロードの一部に対して応答しました。
    4. ただし、パケット 12 では、受信したアプリケーション データ パケットに対して ACK で応答し、その後レスポンス ペイロードで応答する代わりに、バックエンド サーバーは FIN ACK で応答して 接続の終了を開始します。
    5. これは、Message Processor がリクエスト ペイロードを送信している間に、バックエンド サーバーが接続を早期に閉じていることを明確に示しています。
    6. これにより、Message Processor は IOException: Broken Pipe エラーを記録し、クライアントに 503 を返します。

解決策

  1. アプリケーション チームまたはネットワーク チーム(またはその両方)と協力して、バックエンド サーバー側での早期切断の問題を分析して修正します。
  2. バックエンド サーバー アプリケーションが、リクエスト ペイロード全体を受信する前にタイムアウトしたり、接続をリセットしたりしないようにします。
  3. Apigee とバックエンド サーバーの間に中間ネットワーク デバイスまたはレイヤがある場合は、 リクエスト ペイロード全体を受信する前にタイムアウトしないようにしてください。

問題が解決しない場合は、診断情報の収集が必要な場合をご覧ください。

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

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

Public Cloud ユーザーの場合は、次の情報を提供してください。

  • 組織名
  • 環境名
  • API プロキシ名
  • 503 エラーを再現するための完全な curl コマンド
  • 503 Service Unavailable エラーを含むリクエストが記録されているトレース ファイル
  • 503 エラーが現在発生していない場合は、過去に 503 エラーが発生した期間と タイムゾーン情報を提供してください。

Private Cloud ユーザーの場合は、次の情報を提供してください。

  • 失敗したリクエストで確認されたエラー メッセージ全文
  • エラー503が発生している組織、環境名、API プロキシ名
  • API プロキシ バンドル
  • 503 Service Unavailable エラーを含むリクエストが記録されているトレース ファイル
  • NGINX アクセスログ
    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
  • Message Processor ログ
    /opt/apigee/var/log/edge-message-processor/logs/system.log
  • 503 エラーが発生した期間とタイムゾーン情報
  • Tcpdumps エラー発生時に Message Processor とバックエンド サーバーで収集された