アンチパターン: 単一ターゲット サーバーの負荷分散において MaxFailures の値をゼロ以外に設定する

TargetEndpoint 構成は、Apigee Edge がバックエンド サービスまたは API に接続する方法を定義します。この構成により、バックエンド サービスへのリクエスト送信、およびバックエンド サービスからのレスポンス受信を行います。バックエンド サービスは、HTTP / HTTPS サーバー、NodeJS、Hosted Target のいずれかです。

TargetEndpoint では、バックエンド サービスを次のいずれかの方法で起動できます。

  • HTTP または HTTPS サーバーへのダイレクト URL
  • Edge がホストする Node.js スクリプトに対する ScriptTarget
  • Hosted Target 環境にデプロイされた NodeJS に対する HostedTarget
  • TargetServer 構成

また、Service Callout ポリシーを使用して、任意の外部サービスを API プロキシフローから呼び出すこともできます。このポリシーを使用すると、ポリシー自身に直接、または TargetServer 構成を使用して、HTTP / HTTPS ターゲット URL を定義できます。

TargetServer 構成

TargetServer 構成は、実際のエンドポイント URL を TargetEndpoint 構成から、または Service Callout ポリシー内で分離します。TargetEndpoint では、TargetServer は URL ではなく名前で参照されます。TargetServer 構成には、バックエンド サービスのホスト名やポート番号、その他の詳細情報が格納されます。

次に、TargetServer 構成の例を示します。

<TargetServer name="target1">
      <Host>www.mybackendservice.com</Host>
      <Port>80</Port>
      <IsEnabled>true</IsEnabled>
    </TargetServer>
    

TargetServer を使用することで、環境ごとに異なる構成を用意できます。TargetEndpoint ポリシーと Service Callout ポリシーは、LoadBalancer を使用して、1 つまたは複数の名前付き TargetServer によって構成できます。負荷分散が組み込みでサポートされるため、構成されたバックエンド サーバー インスタンス間での API の可用性、およびフェイルオーバーが強化されます。

次に、TargetServer を使用した TargetEndpoint 構成の例を示します。

<TargetEndpoint name="default">
        <HTTPTargetConnection>>
          <LoadBalancer>
            <Server name="target1"/>
          <Server name="target2"/>
          </LoadBalancer>
        </HTTPTargetConnection>
    </TargetEndpoint>
    

MaxFailures

MaxFailures 構成は、ターゲット サーバーへのリクエストの最大失敗回数を指定します。この回数に達したターゲット サーバーは停止状態としてマークされ、以降のすべてのリクエストに対するローテーションから除外されます。

次に、MaxFailures を指定した構成の例を示します。

<TargetEndpoint name="default">
        <HTTPTargetConnection>
          <LoadBalancer>
            <Server name="target1"/>
           <Server name="target2"/>
           <MaxFailures>5</MaxFailures>
          </LoadBalancer>
        </HTTPTargetConnection>
    </TargetEndpoint>
    

この例では、「target1」へのリクエストが連続して 5 回失敗すると、「target1」はローテーションから除外され、以降のすべてのリクエストは「target2」のみに送られます。

アンチパターン

TargetEndpoint の LoadBalancer に TargetServer を 1 つしか指定しない構成、または Service Callout ポリシーの MaxFailures を 0 以外の値に設定する構成は、悪影響が生じる可能性があり、おすすめできません。

「target1」という名前の 1 つの TargetServer だけが存在し、MaxFailures が 5(0 以外の値)に設定されている次の構成例について考えてみます。

<TargetEndpoint name="default">
      <HTTPTargetConnection>
          <LoadBalancer>
            <Algorithm>RoundRobin</Algorithm>
            <Server name="target1" />
            <MaxFailures>5</MaxFailures>
          </LoadBalancer>
      </HTTPTargetConnection>
    

TargetServer「target1」へのリクエストが 5 回(MaxFailures に指定した数)失敗すると、TargetServer はローテーションから除外されます。しかし、フェイルオーバー先となる別の TargetServer が存在しないため、この構成の API プロキシに対する以降のリクエストはすべて、503 Service Unavailable エラーによって失敗します。

TargetServer「target1」が正常な状態に戻り、正常なレスポンスを返せるようになっても、この API プロキシへのリクエストには、引き続き 503 エラーが返されます。これは、TargetServer が再稼働するようになっても、Edge ではこの TargetServer が自動的にローテーションに戻されることはないためです。この問題を解決するには、Edge 用にAPI プロキシを再デプロイする必要があります。これにより、TargetServer が再度ローテーションに戻されます。

Service Callout ポリシーでこれと同じ構成を使用した場合は、TargetServer「target1」への API リクエストが 5 回失敗した後、リクエストに対して 500 エラーが返されます。

影響

TargetEndpoint の LoadBalancer 構成に TargetServer を 1 つしか指定しない場合、または Service Callout ポリシーの MaxFailures を 0 以外の値に設定する場合は、以下の影響が生じます。

  • API プロキシを再デプロイするまで、API リクエストが失敗し、503 / 500 エラーが返され続けます(リクエストの失敗回数が MaxFailures に指定した数を超えた時点以降)。
  • 問題の原因の診断が難しく、時間がかかる可能性があるため(このアンチパターンについての予備知識がない場合)、停止状態が長引きます。

ベスト プラクティス

  1. 高可用性を実現するため、LoadBalancer 構成には複数の TargetServer を設定します。
  2. MaxFailures を 0 以外の値に設定する場合は、常にヘルスモニターを定義します。失敗回数が MaxFailures に指定した数に達すると、ターゲット サーバーはローテーションから除外されます。HealthMonitor を設置することで、ターゲット サーバーが再稼働した時点ですぐにローテーションに戻されるので、プロキシを再デプロイする必要がありません

    Edge がターゲット サーバーへの接続に使用するものと同じポート番号でヘルスチェックが行われるようにするには、TargetServer ポートと異なる番号でない限り、<TCPMonitor><Port> 子要素を省略することをおすすめします。デフォルトでは、<Port> は TargetServer ポートと同じです。

    HealthMonitor を使用する構成の例:

    <TargetEndpoint name="default">
          <HTTPTargetConnection>
            <LoadBalancer>
              <Algorithm>RoundRobin</Algorithm>
              <Server name="target1" />
              <Server name="target2" />
              <MaxFailures>5</MaxFailures>
            </LoadBalancer>
            <Path>/test</Path>
            <HealthMonitor>
              <IsEnabled>true</IsEnabled>
              <IntervalInSec>5</IntervalInSec>
              <TCPMonitor>
                <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
              </TCPMonitor>
            </HealthMonitor>
          </HTTPTargetConnection>
        </TargetEndpoint>
        
  3. なんらかの制限によって TargetServer が 1 つしか設置できない状況で、HealthMonitor も使用しない場合は、LoadBalancer 構成内で MaxFailures を指定しないでください。

    MaxFailures のデフォルト値は 0 です。 この値の場合、Edge はリクエストが送られるたびにターゲットへの接続を試み、ターゲット サーバーをローテーションから除外することはありません。

関連情報