503 サービス利用不可 - NoActiveTargets - HealthCheckFailures

現在、Apigee Edge のドキュメントを表示しています。
Apigee X のドキュメントをご確認ください
情報

動画

503 エラーについて詳しくは、次の動画をご覧ください。

動画 説明
503 Service Unavailable - NoActiveTargets のトラブルシューティングと解決 以下を確認してください。
  • ターゲット サーバーとヘルスモニターの重要性
  • リアルタイム 503 Service Unavailable - ヘルスチェックの失敗に起因する NoActiveTargets エラーのトラブルシューティングと解決

内容

クライアント アプリケーションが HTTP レスポンス ステータス コード 503 と、Service Unavailable メッセージ、API プロキシ リクエストに関するエラーコード NoActiveTargets を受け取ります。

エラー メッセージ

次のエラー レスポンスが表示されます。

HTTP/1.1 503 Service Unavailable
  

HTTP レスポンスに次のエラー メッセージが表示されます。

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

考えられる原因

通常、API プロキシのターゲット エンドポイント構成で 1 つ以上のターゲット サーバーを使用すると、HTTP レスポンス 503 Service Unavailable(エラーコード NoActiveTargets)が表示されます。

このハンドブックでは、ヘルスチェックの失敗により発生する 503 Service Unavailable とそのエラーコードについて説明します。NoActiveTargets このエラーのその他の原因については、こちらのハンドブックをご覧ください。

ヘルスチェックの失敗

ヘルスチェックの失敗は、API プロキシのターゲット エンドポイントでターゲット サーバーのロード バランシング構成の一部として Health Monitor を構成している場合にのみ検出されます。

ターゲット サーバーがヘルスチェックに失敗すると、Edge はそのサーバーの失敗カウントを増分します。 そのサーバーのヘルスチェックの失敗数が、事前定義されたしきい値(<MaxFailures>)に達すると、Message Processor は次のような警告メッセージをログファイルに記録します。

Apigee-Timer-7 WARN  ADAPTORS.HTTP.FLOW - LBServer.incrementFailureCount() : Max failure count(10) reached for server : mocktarget2{Environment=<orgname>__prod,Application=mocktargetapigee__1,Target=default}
    

警告メッセージには次の情報が含まれています。これにより、どのターゲット サーバーが MaxFailure 数に達したかを把握できます。

  • ターゲット サーバー名
  • 組織名と環境名
  • API プロキシ名
  • ターゲット エンドポイント名

その後、Edge はその特定のサーバーへのそれ以上のリクエストの送信を停止します。LoadBalancer の構成で構成されているすべてのターゲット サーバーが MaxFailure 数に達すると、それ以降の API リクエストには、エラーコード NoActiveTargets とともに 503 Service Unavailable が返されます。

Health Monitor を使用すると、Apigee Edge は、API プロキシを再デプロイすることなく、正常な状態になったらターゲット サーバーを自動的にローテーションに戻すことができます。

ヘルスチェックが失敗する原因としては、次のことが考えられます。

原因 説明 トラブルシューティングの手順を実施できるユーザー
接続タイムアウト エラー Message Processor が、LoadBalancer 構成で指定されたタイムアウト期間内にターゲット サーバーに接続できません。 Edge Private Cloud ユーザー
非セキュア ポートでのセキュア リクエスト
  1. ターゲット サーバーがセキュアなサーバーとして定義されているが、正しくセキュアでないポートが構成されている場合。
  2. ターゲット サーバーがセキュアなサーバーとして定義されているが、ヘルスモニターがセキュアでないポートでヘルスチェックを実行するように構成されている場合。
Edge Private Cloud ユーザー
セキュアポートでの非セキュア リクエスト
  1. ターゲット サーバーが非セキュア サーバーとして定義されているが、セキュアポートが正しく構成されていない場合。
  2. ターゲット サーバーが非セキュア サーバーとして定義されているが、ヘルスモニターがセキュア ポートでヘルスチェックを実行するように構成されている場合。
Edge Private Cloud ユーザー
Health Check API がエラーを返す ヘルスチェック API がエラーまたはレスポンス コードを返す場合、ヘルスモニターの SuccessResponse 要素で指定されたもの以外。 Edge Private Cloud ユーザー

共通の診断手順

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

Trace ツール

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

  1. トレース セッションを有効にして API 呼び出しを行い、問題 503 Service Unavailable(エラーコード NoActiveTargets)を再現します。
  2. 失敗したリクエストのいずれかを選択します。
  3. AX フェーズに移動し、次の図に示すように [Phase Details] セクションを下にスクロールして、リクエストのメッセージ ID(X-Apigee.Message-ID)を確認します。

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

NGINX アクセスログ
このセクションの手順は、Edge Private Cloud ユーザーのみを対象としています。

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-codemessaging.adaptors.http.flow.NoActiveTargets で 503 エラーが発生した場合は、次の例に示すように、1 つ以上のそのようなリクエストのメッセージ ID をメモします。

    503 エラーを示すエントリの例

    ステータス コード、メッセージ ID、障害ソース、障害コードを示すサンプル エントリ

一般的なエラー メッセージ

ターゲット サーバーを使用していて、Message Processor がバックエンド サーバーに接続しようとしたときにエラーが発生すると、Message Processor のログに一般的なエラー メッセージがいくつか記録されます。これらのエラーは、失敗につながった実際の例外またはエラー メッセージの後に記録されます。

Message Processor ログ(/opt/apigee/var/log/edge-message-processor/logs/system.log)で、エラーコード NoActiveTargets503 Service Unavailable に対して確認された一般的なエラー メッセージは次のとおりです。

org:myorg env:prod api:TestTargetServer rev:2 messageid:<messageid>  NIOThread@0 INFO  ADAPTORS.HTTP.FLOW - LBTargetRequestSender.sendRequest() : Failed to send request to target servers : [demo-target] for default{Organization=myorgEnvironment=prod,Application=TestTargetServer__2}

org:myorg env:prod api:TestTargetServer rev:2 messageid:<messageid>  NIOThread@0 ERROR ADAPTORS.HTTP.FLOW - LBTargetRequestSender.sendRequest() : No Active Target server Found for default{Organization=myorgEnvironment=prod,Application=TestTargetServer__2}

org:myorg env:prod api:TestTargetServer rev:2 messageid:<messageid>  NIOThread@0 ERROR ADAPTORS.HTTP.FLOW - LBTargetRequestSender.sendRequest() : Unexpected error while sending request
com.apigee.errors.http.server.ServiceUnavailableException: The Service is temporarily unavailable
	at com.apigee.messaging.adaptors.http.flow.data.LBTargetRequestSender.sendRequest(LBTargetRequestSender.java:299)
	at com.apigee.messaging.adaptors.http.flow.data.LBTargetRequestSender.access$400(LBTargetRequestSender.java:57)
	…<snipped>

これらのエラー メッセージは、エラーが発生したためにバックエンド サーバーにリクエストを送信できなかったことを示します。その結果、Message Processor はクライアントへのレスポンスとして 503 Service Unavailable (エラーコード NoActiveTargets)を送信します。

原因: 接続タイムアウト

診断

  1. 失敗したリクエストのメッセージ ID を特定します
  2. Message Processor のログでメッセージ ID を検索します(/opt/apigee/var/log/edge-message-processor/logs/system.log)。
  3. メッセージ ID に対応する一般的なエラー メッセージが表示されます。ただし、ヘルスチェック失敗の実際の原因を取得するには、一般的なエラー メッセージの上までスクロールして、ヘルスチェック エラーがないか確認します。

    たとえば、次の HEALTH MONITOR エラー メッセージは、ヘルスチェック API リクエストを行ったときに、接続タイムアウト エラーで Message Processor が失敗しました。

    Apigee-Timer-6 ERROR SERVICES.HEALTH_MONITOR - HTTPMonitor.getResponseFromCache() : Error sending request Request URL : https://<BackendServer-Hostname>:443/status
    java.net.ConnectException: Connection timed out (Connection timed out)
    	at java.net.PlainSocketImpl.socketConnect(Native Method)
    	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    …<snipped>
            

    このエラーがヘルスモニターで構成されている MaxFailure 回複数回繰り返されると、次のような警告メッセージが表示されます。

    Apigee-Timer-7 WARN  ADAPTORS.HTTP.FLOW - LBServer.incrementFailureCount() : Max failure count(10) reached for server : mocktarget2{Environment=<orgname>__prod,Application=mocktargetapigee__1,Target=default}
            

    警告メッセージに記載された情報をよくお読みください。エラーコード NoActiveTargets を含む 503 レスポンス コードが発生している、特定の API プロキシで使用されているターゲット サーバーの MaxFailure 数が上限に達していることを確認します。

  4. 上記の例では、ヘルスチェックが connection timed out エラーで失敗しています。telnet コマンドを使用して、各 Message Processor から特定のバックエンド サーバーに直接接続できるかどうかを確認します。
  5. telnet <BackendServer-HostName> 443
          
  6. バックエンド サーバーに接続できる場合は、「Connected to backend-server」などのメッセージが表示されることがあります。一時的な問題の場合、問題が解決する場合もあれば、断続的に発生する場合もあります。ステップ 4 を数回(10 回以上)繰り返し、出力を確認します。
    1. telnet コマンドで一貫してエラーがなければ、問題は解決です。ヘルスチェックの失敗が停止したかどうかを再確認します。「はい」の場合、これ以上の作業は必要ありません。
    2. telnet コマンドでバックエンド サーバーに断続的に接続できない場合は、ネットワークに問題があるか、バックエンド サーバーがビジー状態である可能性があります。
  7. telnet コマンドで一貫してバックエンド サーバーに接続できない場合は、特定のバックエンド サーバーで Message Processor からのトラフィックが許可されていない可能性があります。

解像度

connection timed out エラーが一貫して発生する場合は、バックエンド サーバーにファイアウォールの制限がなく、Apigee Edge Message Processor からのトラフィックが許可されていることを確認します。たとえば、Linux では iptables を使用して、バックエンド サーバー上の Message Processor の IP アドレスからのトラフィックを許可することができます。

問題が解決しない場合は、ネットワーク管理者に問い合わせて、問題を特定し、修正してください。Apigee のサポートが必要な場合は、Apigee サポートにお問い合わせください。

原因: セキュアでないポートでリクエストがセキュアである

診断

  1. 失敗したリクエストのメッセージ ID を特定します
  2. Message Processor のログでメッセージ ID を検索します(/opt/apigee/var/log/edge-message-processor/logs/system.log)。
  3. メッセージ ID に対応する一般的なエラー メッセージが表示されます。 ただし、ヘルスチェック失敗の実際の原因を確認するには、これらの一般的なエラー メッセージの上までスクロールして、ヘルスチェック エラーがないか確認します。

    たとえば、次のように HEALTH MONITOR エラーが表示される場合があります。

    Apigee-Timer-1 ERROR SERVICES.HEALTH_MONITOR - HTTPMonitor.getResponseFromCache() : Error sending request Request URL : https://mocktarget.apigee.net:80/status
    javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
            at sun.security.ssl.InputRecord.handleUnknownRecord(InputRecord.java:710)
            at sun.security.ssl.InputRecord.read(InputRecord.java:527)
            at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
            at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
    …<snipped>
            

    このエラーがヘルスモニターで構成されている MaxFailure 回繰り返されると、次のような警告メッセージが表示されます。

    Apigee-Timer-7 WARN  ADAPTORS.HTTP.FLOW - LBServer.incrementFailureCount() : Max failure count(10) reached for server : mocktarget{Environment=<orgname>__prod,Application=mocktargetapigee__1,Target=default}
            

    警告メッセージに記載された情報をよくお読みください。エラーコード NoActiveTargets を含む 503 レスポンス コードが発生している、特定の API プロキシで使用されているターゲット サーバーの MaxFailure 数が上限に達していることを確認します。

  4. ヘルスチェックが失敗しました。エラー:
    Error sending request Request URL : https://mocktarget.apigee.net:80/statuscode/200
    javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
          

    エラー メッセージと URL から、この問題の原因がセキュアでないポート 80安全な呼び出し(HTTPS)が行われたことが示されています。

    このエラーは、次の 2 つのシナリオで発生する可能性があります。

    • セキュア ターゲット サーバーが非セキュア ポートで定義された
    • 安全なターゲット サーバーが定義されているが、Health Monitor が非セキュア ポートで構成されている

    セキュア ターゲットの非セキュア ポート

    シナリオ 1: セキュアなターゲット サーバーを非セキュア ポートで定義

    セキュアなターゲット サーバーを定義していても、ポートが 80 などの非セキュアである場合、このエラーが発生します。以下の手順で、この問題の原因かどうかを確認します。

    1. ターゲット エンドポイントの構成で使用されているターゲット サーバーの定義を確認します。
    2. Get TargetServer API を使用して、ターゲット サーバー定義を取得します。

      ターゲット サーバー定義の出力

      <TargetServer name="mocktarget">
        <Host>mocktarget.apigee.net</Host>
        <Port>80</Port>
        <IsEnabled>true</IsEnabled>
        <SSLInfo>
            <Enabled>true</Enabled>
        </SSLInfo>
      </TargetServer>
                

      上記の例では、SSLInfo ブロックで示されているように、定義によりターゲット サーバー mocktarget がセキュア サーバーであることが示されています。ただし、セキュアでないポート 80 が構成されています。

    3. ターゲット エンドポイントの構成で、ターゲット サーバーの Health Monitor 構成を確認します。

      ヘルスモニターの構成

      <HealthMonitor>
        <IsEnabled>true</IsEnabled>
        <IntervalInSec>5</IntervalInSec>
        <HTTPMonitor>
          <Request>
            <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
            <SocketReadTimeoutInSec>30</SocketReadTimeoutInSec>
            <Verb>GET</Verb>
            <Path>/statuscode/200</Path>
          </Request>
          <SuccessResponse>
            <ResponseCode>200</ResponseCode>
          </SuccessResponse>
        </HTTPMonitor>
      </HealthMonitor>
                

      上記のヘルスモニターの構成では、<Port> 要素が指定されていません。この場合、Edge の Message Processor は、ターゲット サーバー定義で指定されたポート(80)を使用してヘルスチェック API 呼び出しを行います。

    4. 上記の情報に基づくと、ターゲット サーバーがセキュア サーバーとして定義されている(SSLInfo ブロックが有効になっている)ものの、セキュアでないポート 80 が設定されていることが、このエラーの原因です。

    セキュア ターゲットの非セキュア HM ポート

    シナリオ 2: 安全なターゲット サーバーが定義されているが、Health Monitor がセキュアでないポートで構成されている

    セキュアなターゲット サーバーを定義していても、Health Monitor がセキュアでないポート(80 など)で構成されている場合、このエラーが発生します。以下の手順に沿って、この問題の原因かどうかを確認します。

    1. ターゲット エンドポイントの構成で使用されているターゲット サーバーの定義を確認します。

      Get TargetServer API を使用して、ターゲット サーバー定義を取得します。

      ターゲット サーバー定義の出力

      <TargetServer name="mocktarget">
        <Host>mocktarget.apigee.net</Host>
        <Port>443</Port>
        <IsEnabled>true</IsEnabled>
        <SSLInfo>
            <Enabled>true</Enabled>
        </SSLInfo>
      </TargetServer>
              

      上記の例では、SSLInfo ブロックで示されているように、定義によりターゲット サーバー mocktarget が安全なサーバーであることが示されています。

    2. 次に、ターゲット エンドポイント構成でターゲット サーバーの Health Monitor 構成を確認します。

      ヘルスモニターの構成

      <HealthMonitor>
        <IsEnabled>true</IsEnabled>
        <IntervalInSec>5</IntervalInSec>
        <HTTPMonitor>
          <Request>
            <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
         	<SocketReadTimeoutInSec>30</SocketReadTimeoutInSec>
            <Port>80</Port>
            <Verb>GET</Verb>
            <Path>/statuscode/200</Path>
          </Request>
          <SuccessResponse>
            <ResponseCode>200</ResponseCode>
          </SuccessResponse>
        </HTTPMonitor>
              

      上記の例では、ヘルスモニターは、<Port> 要素で示されているセキュアでないポート 80 で構成されています。

    3. 上記の情報に基づくと、このエラーの原因は、ターゲット サーバーがセキュア サーバーとして定義され(SSLInfo ブロックが有効になっている)セキュア ポート 443 を使用しているのに、ヘルスモニターがセキュアでないポート 80(<Port> 要素で指定)でヘルスチェックを実行するように構成されていることです。

      つまり、この場合、Edge はヘルスチェック API をセキュアでないポート 80 でのセキュアな呼び出しとして実行し、上記のエラーで失敗します。

解像度

セキュア ターゲットの非セキュア ポート

シナリオ 1: セキュアなターゲット サーバーを非セキュア ポートで定義

このエラーを修正するには、適切なセキュアポートを使用するようにターゲット サーバーの定義を更新します。

TargetServer API の更新を使用してターゲット サーバー定義を更新し、次の例に示すように安全なポート(443 など) が使用されていることを確認します。

<TargetServer name="mocktarget">
  <Host>mocktarget.apigee.net</Host>
  <Port>443</Port>
  <IsEnabled>true</IsEnabled>
  <SSLInfo>
      <Enabled>true</Enabled>
  </SSLInfo>
</TargetServer>
    

セキュア ターゲットの非セキュア HM ポート

シナリオ 2: 安全なターゲット サーバーが定義されているが、Health Monitor がセキュアでないポートで構成されている

このエラーを解決するには、次の手順を行います。

  1. 次のように、安全なポート(443 など)を使用するようにヘルス モニターの構成を変更して、失敗した API プロキシのターゲット エンドポイント構成でターゲット サーバーのヘルスチェックを実行します。
    <HealthMonitor>
      <IsEnabled>true</IsEnabled>
      <IntervalInSec>5</IntervalInSec>
      <HTTPMonitor>
        <Request>
          <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
        <SocketReadTimeoutInSec>30</SocketReadTimeoutInSec>
          <Port>443</Port>
          <Verb>GET</Verb>
          <Path>/statuscode/200</Path>
        </Request>
        <SuccessResponse>
          <ResponseCode>200</ResponseCode>
        </SuccessResponse>
      </HTTPMonitor>
    </HealthMonitor>
            
  2. API プロキシへの変更を保存します。

原因: セキュアポートでの安全でないリクエスト

診断

  1. 失敗したリクエストのメッセージ ID を特定します
  2. Message Processor のログでメッセージ ID を検索します(/opt/apigee/var/log/edge-message-processor/logs/system.log)。
  3. メッセージ ID に対応する一般的なエラー メッセージが表示されます。 ただし、ヘルスチェック失敗の実際の原因を確認するには、これらの一般的なエラー メッセージの上までスクロールして、ヘルスチェック エラーがないか確認します。

    たとえば、次のように HEALTH MONITOR エラーが表示される場合があります。

    Apigee-Timer-2 ERROR SERVICES.HEALTH_MONITOR - HTTPMonitor.getResponseFromCache() : Error sending request Request URL : http://mocktarget.apigee.net:443/status
    java.net.SocketException: Unexpected end of file from server
    	at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:851)
    	at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
    	at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:848)
    	at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
    	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
    …<snipped>
              

    このエラーがヘルスモニターで構成されている MaxFailure 回繰り返されると、次のような警告メッセージが表示されます。

    Apigee-Timer-7 WARN  ADAPTORS.HTTP.FLOW - LBServer.incrementFailureCount() : Max failure count(10) reached for server : mocktarget{Environment=<orgname>__prod,Application=mocktargetapigee__1,Target=default}
              

    警告メッセージに記載された情報をよくお読みください。エラーコード NoActiveTargets を含む 503 レスポンス コードが発生している、特定の API プロキシで使用されているターゲット サーバーの MaxFailure 数が上限に達していることを確認します。

  4. ヘルスチェックが失敗しました。エラー:
    Error sending request Request URL : http://mocktarget.apigee.net:443/status
    java.net.SocketException: Unexpected end of file from server
          

    エラー メッセージと URL から、この問題の原因はセキュアポート 443安全でない呼び出し(HTTP)が行われたことが示されています。

    このエラーは、次の 2 つのシナリオで発生する可能性があります。

    • セキュアポートで定義された非セキュア ターゲット サーバー
    • セキュアでないターゲット サーバーが定義されているが、Health Monitor がセキュアポートで構成されている

    非セキュア ターゲット セキュアポート

    シナリオ 1: セキュアでないターゲット サーバーにセキュアポートを定義する

    セキュアでないターゲット サーバーを定義していても、ポートが 443 などのセキュアであるとすると、このエラーが発生します。以下の手順で、この問題の原因かどうかを確認します。

    1. ターゲット エンドポイントの構成で使用されているターゲット サーバーの定義を確認します。

      Get TargetServer API を使用して、ターゲット サーバー定義を取得します。

      ターゲット サーバー定義の出力

      <TargetServer name="mocktarget">
        <Host>mocktarget.apigee.net</Host>
        <Port>443</Port>
        <IsEnabled>true</IsEnabled>
      </TargetServer>
                    

      上記の例では、SSLInfo ブロックがないため、ターゲット サーバー mocktarget がセキュアでないサーバーであることが定義により示されています。しかし、セキュアなポート 443 が正しく構成されていません

    2. ターゲット エンドポイントの構成で、ターゲット サーバーの Health Monitor 構成を確認します。

      ヘルスモニターの構成

      <HealthMonitor>
        <IsEnabled>true</IsEnabled>
        <IntervalInSec>5</IntervalInSec>
        <HTTPMonitor>
          <Request>
            <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
            <SocketReadTimeoutInSec>30</SocketReadTimeoutInSec>
            <Verb>GET</Verb>
            <Path>/statuscode/200</Path>
          </Request>
          <SuccessResponse>
            <ResponseCode>200</ResponseCode>
          </SuccessResponse>
        </HTTPMonitor>
      </HealthMonitor>
                      

      上記のヘルスモニターの構成では、<Port> 要素が指定されていません。この場合、Edge の Message Processor は、ターゲット サーバーの定義で指定されたポート(443)を使用します。

    3. 上記の情報に基づくと、ターゲット サーバーがセキュアでないサーバーとして定義されている(SSLInfo ブロックが定義されていないため)が、セキュア ポート 443 がこのエラーの原因となっています。

      つまり、Edge はヘルスチェックをセキュアポート 443 を使用したセキュアでない呼び出しとして行い、上記のエラーで失敗します。

    非セキュア ターゲットのセキュア HM ポート

    シナリオ 2: セキュアでないターゲット サーバーが定義されているが、Health Monitor がセキュアポートで構成されている

    セキュアでないターゲット サーバーを定義していても、Health Monitor が 443 などのセキュアポートで構成されている場合、このエラーが発生します。以下の手順で、この問題の原因かどうかを確認します。

    1. ターゲット エンドポイントの構成で使用されているターゲット サーバーの定義を確認します。

      Get TargetServer API を使用して、ターゲット サーバー定義を取得します。

      ターゲット サーバー定義の出力

      <TargetServer name="mocktarget">
        <Host>mocktarget.apigee.net</Host>
        <Port>80</Port>
        <IsEnabled>true</IsEnabled>
      </TargetServer>
              

      上記の例では、この定義により、ターゲット サーバーが mocktarget セキュアでないサーバーであることがSSLInfo ブロックがないため、正しく非セキュアに設定されていました。

    2. 次に、ターゲット エンドポイント構成でターゲット サーバーの Health Monitor 構成を確認します。

      ヘルスモニターの構成

      <HealthMonitor>
        <IsEnabled>true</IsEnabled>
        <IntervalInSec>5</IntervalInSec>
        <HTTPMonitor>
          <Request>
            <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
         	<SocketReadTimeoutInSec>30</SocketReadTimeoutInSec>
            <Port>443</Port>
            <Verb>GET</Verb>
            <Path>/statuscode/200</Path>
          </Request>
          <SuccessResponse>
            <ResponseCode>200</ResponseCode>
          </SuccessResponse>
        </HTTPMonitor>
      </HealthMonitor>
            

      上記の例では、ヘルスモニターは、<Port> 要素で示されているセキュアポート 443 で構成されています。

    3. 上記の情報に基づくと、このエラーの原因は、ターゲット サーバーが非セキュア ポート 80 で正しく非セキュア サーバーとして定義されている(SSLInfo ブロックが定義されていないため)ものの、ヘルスモニターがセキュアポート 443<Port> 要素で指定)でヘルスチェックを実行するように構成されていることです。

      つまり、この場合、Edge はヘルスチェックをセキュア ポート 443 を使用した非セキュアな呼び出しとして行い、前述のエラーで失敗します。

解像度

非セキュア ターゲット セキュアポート

シナリオ 1: セキュアでないターゲット サーバーにセキュアポートを定義する

このエラーを修正するには、適切なセキュアポートを使用するようにターゲット サーバーの定義を更新します。

ターゲット サーバー API の更新を使用してターゲット サーバーの定義を更新し、以下の例に示すようにセキュアでないポート(80 など)が使用されていることを確認します。

<TargetServer name="mocktarget">
  <Host>mocktarget.apigee.net</Host>
  <Port>80</Port>
  <IsEnabled>true</IsEnabled>
</TargetServer>
              

非セキュア ターゲットのセキュア HM ポート

シナリオ 2: セキュアでないターゲット サーバーが定義されているが、Health Monitor がセキュアポートで構成されている

このエラーを解決するには、次の手順を行います。

  1. 次のように、ヘルスモニターの構成から <Port> 要素を削除するか、セキュアでないポート(80 など) を使用するようにヘルス モニターの構成を変更して、失敗した API プロキシのターゲット エンドポイント構成でターゲット サーバーのヘルスチェックを実行します。
    <HealthMonitor>
      <IsEnabled>true</IsEnabled>
      <IntervalInSec>5</IntervalInSec>
      <HTTPMonitor>
        <Request>
          <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
       	<SocketReadTimeoutInSec>30</SocketReadTimeoutInSec>
          <Port>80</Port>
          <Verb>GET</Verb>
          <Path>/statuscode/200</Path>
        </Request>
        <SuccessResponse>
          <ResponseCode>200</ResponseCode>
        </SuccessResponse>
      </HTTPMonitor>
    </HealthMonitor>
            
  2. API プロキシへの変更を保存します。

原因: ヘルスチェック API がエラーを返す

診断

  1. 失敗したリクエストのメッセージ ID を特定します
  2. Message Processor のログでメッセージ ID を検索します(/opt/apigee/var/log/edge-message-processor/logs/system.log)。
  3. メッセージ ID に対応する一般的なエラー メッセージが表示されます。 ただし、ヘルスチェック失敗の実際の原因を確認するには、これらの一般的なエラー メッセージの上までスクロールして、ヘルスチェックに関するエラーや警告を確認します。

    たとえば、次のように HEALTH MONITOR 警告が表示される場合があります。

    Apigee-Timer-7 INFO  SERVICES.HEALTH_MONITOR - HTTPMonitor.sendRequest() : HTTPMonitor.monitor() : Connecting to https://mocktarget.apigee.net:443/status/200
    Apigee-Timer-7 WARN  SERVICES.HEALTH_MONITOR - HTTPMonitor.monitor() : HTTP response code from health monitoring service does not match.Expected response code : [200]. Received response code : 404
            

    このエラーがヘルスモニターで構成されている MaxFailure 回繰り返されると、次のような警告メッセージが表示されます。

    Apigee-Timer-7 WARN  ADAPTORS.HTTP.FLOW - LBServer.incrementFailureCount() : Max failure count(10) reached for server : mocktarget{Environment=<orgname>__prod,Application=mocktargetapigee__1,Target=default}
            

    警告メッセージに記載された情報をよくお読みください。エラーコード NoActiveTargets を含む 503 レスポンス コードが発生している、特定の API プロキシで使用されているターゲット サーバーの MaxFailure 数が上限に達していることを確認します。

  4. ヘルスチェックから次の警告メッセージが返されました。
    HTTP response code from health monitoring service does not match.Expected response code : [200]. Received response code : 404
          

    上記の警告メッセージは、ヘルスチェック API で想定されるレスポンス コードが 200 であるものの、実際に受信したレスポンスは 404 であることを示しています。したがって、これは失敗として扱われます。

  5. ヘルスチェック API からのエラー レスポンスの原因を調査する前に、Edge でヘルスチェック API のレスポンス コードが 200 と想定されている理由を確認してください。これについては、ターゲット エンドポイント構成でターゲット サーバーの Health Monitor 構成を確認します。

    ヘルスモニターの構成

    <HealthMonitor>
      <IsEnabled>true</IsEnabled>
      <IntervalInSec>5</IntervalInSec>
      <HTTPMonitor>
        <Request>
          <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
       	<SocketReadTimeoutInSec>30</SocketReadTimeoutInSec>
          <Port>443</Port>
          <Verb>GET</Verb>
          <Path>/status/200</Path>
        </Request>
        <SuccessResponse>
          <ResponseCode>200</ResponseCode>
        </SuccessResponse>
      </HTTPMonitor>
    </HealthMonitor>
            

    ヘルスモニターの構成は、<SuccessResponse> 要素の下に 200 レスポンス コードで構成されています。つまり、Edge がヘルスチェック API から 200 以外のレスポンス コード(400、401、404、500 など)を受け取ると、エラーとして処理され、失敗カウントが加算されます。

  6. ヘルスチェック API からのエラー レスポンスの原因を調査するには、次の手順を行います。
    1. Message Processor ログで、警告メッセージの前のメッセージを確認します。
      Apigee-Timer-7 INFO  SERVICES.HEALTH_MONITOR - HTTPMonitor.sendRequest() : HTTPMonitor.monitor() : Connecting to https://mocktarget.apigee.net:443/status/200
                

      このメッセージに表示されたヘルスチェックの URL をメモします。

    2. Message Processor からこの URL を直接呼び出して、実際のレスポンスを確認できます。
      curl -i https://mocktarget.apigee.net:443/status/200
                

      Message Processor のログを確認すると、上記の呼び出しからのレスポンスは 404 になります。

      < HTTP/2 404
                
    3. これは、ヘルスチェック URL の直接呼び出しでも、同じレスポンス コード 404 で失敗することを示しています。ヘルスチェックの URL が正しくないか、この URL の一部としてアクセスされているリソースが利用できなくなっていることを意味します。
    4. 上記のヘルスチェック API の例では、ヘルスモニターの構成で誤った URL が使用されたことが原因で、問題が発生しています。Mock Target API により、正しい URL は https://mocktarget.apigee.net:443/statuscode/200 であることが判明しました。
  7. 他のエラー レスポンスが表示された場合は、上記の手順に沿って同じ原因を特定します。必要に応じて、バックエンド チームと連携します。

解像度

  1. バックエンド サーバーのヘルスチェック API の問題を修正します。
  2. 上記の例の問題を解決するには:
    1. 次のように、ヘルスモニター構成の <Path> 要素を /statuscode/200 に変更します。
      <Path>/statuscode/200</Path>
              
    2. API プロキシに変更を保存します。

問題が解決しない場合は、診断情報の収集が必要な場合に進みます。

API Monitoring を使用して問題を診断する

API Monitoring を使用すると、問題領域をすばやく分離して、エラー、パフォーマンス、レイテンシの問題とその原因(デベロッパー アプリ、API プロキシ、バックエンド ターゲット、API プラットフォームなど)を診断できます。

サンプル シナリオを実行し、API Monitoring を使用して API での 5xx 問題のトラブルシューティング方法を確認します。たとえば、messaging.adaptors.http.flow.NoActiveTargets の障害数が特定のしきい値を超えたときに通知されるようにアラートを設定できます。

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

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

  1. Public Cloud をご利用の場合は、次の情報をご入力ください。
    1. 組織名
    2. 環境名
    3. API プロキシ名
    4. 完全な curl コマンドでエラーを再現する
    5. 503 Service Unavailable(エラーコード NoActiveTargets)のリクエストを含むトレース ファイル
  2. Private Cloud をご利用の場合は、次の情報を提供してください。
    1. 確認された完全なエラー メッセージ
    2. 環境名
    3. API プロキシ バンドル
    4. 503 Service Unavailable(エラーコード NoActiveTargets)のリクエストを含むトレース ファイル
    5. NGINX アクセスログ

      (/opt/apigee/var/log/edge-router/nginx/<org>~<env>.<port#>_access_log)

    6. Message Processor のログ

      (/opt/apigee/var/log/edge-message-processor/logs/system.log)