アンチパターン: MaxFailures の値をゼロ以外に設定した単一ターゲット サーバーのロード バランシング

現在、ApigeeApigee ハイブリッドのドキュメントを表示しています。
Apigee Edge ドキュメントを表示する。

TargetEndpoint 構成は、Apigee がバックエンド サービスまたは API に接続する方法を定義します。これは、リクエストを送信し、バックエンド サービスとの間のレスポンスを受け取ります。バックエンド サービスは HTTP / HTTPS サーバーまたは NodeJS サーバーです。

TargetEndpoint のバックエンド サービスは、次のいずれかの方法で呼び出すことができます。

  • HTTP または HTTPS サーバーへのダイレクト URL
  • TargetServer 構成

同様に、ServiceCallout ポリシーを使用して、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(非ゼロ値)に設定されている次の構成例について考えてみます。

<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 エラーが返されます。これは、ターゲットが再度稼働した後でも、Apigee は自動的に TargetServer をローテーションに戻さないためです。この問題を解決するには、API プロキシを再デプロイして、Apigee が TargetServer をローテーションに戻すようにする必要があります。

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

影響

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

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

ベスト プラクティス

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

    ターゲット サーバーに接続するために Apigee が使用するものと同じポート番号でヘルスチェックが実行されるよう、Apigee では 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 です。これは、Apigee は各リクエストのためにターゲットへの接続を常に試み、ターゲット サーバーをローテーションから除外しないことを意味します。

関連情報