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

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

動画

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

動画 説明
503 Service Unavailable - NoActiveTargets のトラブルシューティングと解決 以下の内容を学習します。
  • ターゲット サーバーとヘルスモニターの重要性
  • ヘルスチェックの失敗が原因で発生したリアルタイムの 503 Service Unavailable - NoActiveTargets エラーのトラブルシューティングと解決

症状

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

エラー メッセージ

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

HTTP/1.1 503 Service Unavailable
  

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

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

考えられる原因

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

このプレイブックでは、ヘルスチェックの失敗が原因で発生したエラーコード NoActiveTargets503 Service Unavailable について説明します。このエラーの他の原因については、こちらのハンドブックを参照してください。

ヘルスチェックの失敗

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

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

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 リクエストは 503 Service Unavailable で応答され、エラーコード NoActiveTargets が返されます。

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

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

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

共通の診断手順

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

Trace ツール

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

  1. トレース セッションを有効にして API 呼び出しを行い、503 Service Unavailable(エラーコード NoActiveTargets)の問題を再現します。
  2. 失敗したリクエストのいずれかを選択します。
  3. AX フェーズに移動し、次の図に示すように、[フェーズの詳細] セクションを下にスクロールして、リクエストのメッセージ 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.NoActiveTargets の 503 エラーがある場合は、次の例に示すように、1 つ以上のリクエストのメッセージ ID をメモします。

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

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

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

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

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

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 は、エラーコード NoActiveTargets を含む 503 Service Unavailable をクライアントへのレスポンスとして送信します。

原因: 接続タイムアウト

診断

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

    たとえば、次の 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 サポートにお問い合わせください。

原因: 保護されていないポートでの保護されたリクエスト

診断

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

    たとえば、次のように 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 つのシナリオで発生する可能性があります。

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

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

    シナリオ 1: セキュアでないポートで定義されたセキュア ターゲット サーバー

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

    1. ターゲット エンドポイントの構成で使用されているターゲット サーバーの定義を確認します。
    2. ターゲット サーバーの取得 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. 次に、ターゲット エンドポイントの構成でターゲット サーバーのヘルスモニターの構成を確認します。

      ヘルスモニターの構成

      <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 は、ヘルスチェック API 呼び出しを行うために、ターゲット サーバー定義で指定されたポート(80)を使用します。

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

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

    シナリオ 2: セキュア ターゲット サーバーが定義されているが、セキュアでないポートで構成されたヘルスモニター

    セキュア ターゲット サーバーを定義しているにもかかわらず、ヘルスモニターが 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. 次に、ターゲット エンドポイント構成でターゲット サーバーのヘルスモニター構成を確認します。

      ヘルスモニターの構成

      <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 は安全でないポート 80 でヘルスチェック API を安全な呼び出しとして実行し、前述のエラーで失敗します。

解決策

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

シナリオ 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: セキュア ターゲット サーバーが定義されているが、セキュアでないポートで構成されたヘルスモニター

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

  1. 次のように、失敗した API プロキシのターゲット エンドポイント構成で、安全なポート(443 など)を使用してターゲット サーバーのヘルスチェックを実行するようにヘルスモニターの構成を変更します。
    <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 のログ(/opt/apigee/var/log/edge-message-processor/logs/system.log)でメッセージ ID を検索します。
  3. メッセージ ID に対応する一般的なエラー メッセージが表示されます。ただし、ヘルスチェックの失敗の実際の原因を特定するには、上記の一般的なエラー メッセージまでスクロールして、HEALTH MONITOR エラーがないか確認します。

    たとえば、次のように 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 つのシナリオで発生する可能性があります。

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

    セキュアでないターゲット セキュアポート

    シナリオ 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. 次に、ターゲット エンドポイント構成でターゲット サーバーのヘルスモニター構成を確認します。

      ヘルスモニターの構成

      <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 のメッセージ プロセッサは、ターゲット サーバーの定義で指定されたポート(443)を使用します。

    3. 上記の情報に基づくと、このエラーの原因は、ターゲット サーバーが安全でないサーバーとして定義されている(SSLInfo ブロックが定義されていない)にもかかわらず、安全なポート 443 が使用されていることです。

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

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

    シナリオ 2: 非セキュア ターゲット サーバーが定義されているが、セキュア ポートで構成されたヘルスモニター

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

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

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

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

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

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

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

      ヘルスモニターの構成

      <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: 非セキュア ターゲット サーバーが定義されているが、セキュア ポートで構成されたヘルスモニター

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

  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 のログ(/opt/apigee/var/log/edge-message-processor/logs/system.log)でメッセージ ID を検索します。
  3. メッセージ ID に対応する一般的なエラー メッセージが表示されます。ただし、ヘルスチェックの失敗の実際の原因を特定するには、上記の一般的なエラー メッセージまでスクロールして、HEALTH MONITOR エラー/警告がないか確認します。

    たとえば、次のように 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 と想定している理由を特定します。これを行うには、ターゲット エンドポイント構成でターゲット サーバーのヘルスモニター構成を確認します。

    ヘルスモニターの構成

    <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 が使用されているため、問題が発生しています。正しい URL は、疑似ターゲット APIhttps://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. エラーコード NoActiveTargets で 503 Service Unavailable のリクエストを含むトレース ファイル
  2. Private Cloud をご利用の場合は、次の情報を提供してください。
    1. 確認したエラー メッセージ全文
    2. 環境名
    3. API プロキシ バンドル
    4. エラーコード NoActiveTargets で 503 Service Unavailable のリクエストを含むトレース ファイル
    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