アンチパターン: エラー レスポンスをキャッシュに保存する

現在、ApigeeApigee ハイブリッドのドキュメントを表示しています。
Apigee Edge のドキュメントはこちらをご覧ください。

キャッシュ保存とは、後から参照できるように、キャッシュと呼ばれる一時的なストレージ領域にデータを保存するプロセスです。データをキャッシュに保存することで以下が可能になり、パフォーマンス上の大きな利点が得られます。

  • データを高速に取得
  • データを何度も繰り返し生成する必要がなく、処理時間を短縮
  • バックエンド サーバーへの API リクエストの送信を防ぎ、バックエンド サーバーのオーバーヘッドを低減
  • システムおよびアプリケーション リソースを効率的に使用
  • API の応答時間を改善

変更頻度の低いデータに頻繁にアクセスする必要がある場合は、データをキャッシュに保存することを強くおすすめします。

Apigee では、ランタイムにデータをキャッシュに保存して、データを高速かつ永続的に取得できます。キャッシュ機能を使用するには、PopulateCache ポリシーLookupCache ポリシーInvalidateCache ポリシーResponseCache ポリシーを使用します。

このセクションでは、ResponseCache ポリシーについて見てみましょう。Apigee プラットフォームの ResponseCache ポリシーを使用すると、バックエンド サーバーからのレスポンスをキャッシュに保存できます。クライアント アプリケーションが同じバックエンド リソースを繰り返しリクエストし、リソースが定期的に更新される場合は、このポリシーを使用してレスポンスをキャッシュに保存できます。ResponseCache ポリシーを使用すると、キャッシュに保存したレスポンスが返されるので、バックエンド サーバーへの不要なリクエストを防ぐことができます。

ResponseCache ポリシーにより、次のことを実現できます。

  • バックエンドに到達するリクエスト数を低減
  • ネットワーク帯域幅を低減
  • API のパフォーマンスと応答時間を向上

アンチパターン

ResponseCache ポリシーを使用すると、デフォルトの設定では、どのステータス コードの HTTP レスポンスもキャッシュに保存されます。つまり、成功とエラーの両方のレスポンスがキャッシュに保存されます。

デフォルト構成の ResponseCache ポリシーの例を示します。

<!-- /antipatterns/examples/1-1.xml -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ResponseCache async="false" continueOnError="false" enabled="true" name="TargetServerResponseCache">
  <DisplayName>TargetServer ResponseCache</DisplayName>
  <CacheKey>
    <Key Fragment ref="request.uri" /></CacheKey>
    <Scope>Exclusive</Scope>
    <ExpirySettings>
      <TimeoutInSec ref="flow.variable.here">600</TimeoutInSec>
    </ExpirySettings>
  <CacheResource>targetCache</CacheResource>
</ResponseCache>

デフォルト構成では、ResponseCache ポリシーはエラー レスポンスをキャッシュに保存します。ただし、エラー レスポンスをキャッシュに保存する場合は、悪影響を十分に検討しておく必要があります。

  • シナリオ 1: 障害が一時的なもので、いつ解決されるか不明な場合、エラー レスポンスをキャッシュに保存していると、問題が解決した後もエラー レスポンスが送信されてしまう可能性があります。

    または

  • シナリオ 2: 障害が一定期間継続している場合は、問題の解決後にレスポンスをキャッシュに保存しないようにコードを修正する必要があります。

以下では、この 2 つのシナリオについて詳しく説明します。

シナリオ 1: バックエンド / リソースに関連する一時的な障害

バックエンド サーバーの障害が以下のような理由で発生したとします。

  • 一時的なネットワーク障害
  • バックエンド サーバーが極度のビジー状態で、一時的にリクエストに応答できない
  • リクエストされたバックエンド リソースが一時的に削除されているか、使用できない
  • 一時的に処理が集中しているため、バックエンド サーバーのレスポンスが遅くなっている

上記のどの場合も、障害がいつまで続くかは不明であり、再び成功レスポンスを受け取るようになる可能性があります。エラー レスポンスをキャッシュに保存すると、バックエンド サーバーの問題が解決した後も、エラー レスポンスがユーザーに送信される可能性があります。

シナリオ 2: バックエンド / リソースに関連する長期的または一定期間の障害

バックエンドの障害が一定時間発生することが事前にわかっているとします。たとえば、次のことを事前に把握している場合です。

  • 特定のバックエンド リソースが 1 時間だけ使用できない

    または

  • 突然のサイトの障害、スケーリングに関する問題、メンテナンス、アップグレードなどが原因で、24 時間バックエンド サーバーが削除されるか、使用できない状態になる。

この情報を使用して、ResponseCache ポリシーでキャッシュの有効期限を適切に設定することで、エラー レスポンスが長期間キャッシュに保存されないようにできます。ただし、バックエンド サーバーまたはリソースが再度使用可能になった時点で、エラー レスポンスがこれ以上キャッシュに保存されないように、ポリシーを修正する必要があります。バックエンド サーバーで一時的な障害や 1 回限りの障害が発生した場合に、レスポンスをキャッシュに保存し続けると、最終的に上記の「シナリオ 1」で説明した問題が発生することになります。

影響

  • エラー レスポンスをキャッシュに保存すると、バックエンド サーバーの問題が解決した後もエラー レスポンスが送信される可能性があります。
  • ユーザーは、バックエンド サーバーからのエラー レスポンスをキャッシュに保存していることが原因だとわからず、問題のトラブルシューティングに無駄な労力を費やす結果になる可能性があります。

ベスト プラクティス

  • エラー レスポンスをレスポンス キャッシュに保存しないでください。エラー レスポンスがキャッシュに保存されないようにするには、下記のコード スニペットのように、ResponseCache ポリシー<ExcludeErrorResponse> 要素を true に設定します。このように構成すると、成功コードが変更されていない限り、デフォルトの成功コード 200~205 のレスポンスだけがキャッシュに保存されます。
    <!-- /antipatterns/examples/1-2.xml -->
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ResponseCache async="false" continueOnError="false" enabled="true" name="TargetServerResponseCache">
      <DisplayName>TargetServerResponseCache</DisplayName>
      <CacheKey>
        <KeyFragment ref="request.uri" />
      </CacheKey>
      <Scope>Exclusive</Scope>
      <ExpirySettings>
        <TimeoutinSec ref="flow.variable.here">600</TimeoutinSec>
      </ExpirySettings>
      <CacheResource>targetCache</CacheResource>
      <ExcludeErrorResponse>true</ExcludeErrorResponse>
    </ResponseCache>
    
  • なんらかの理由でエラー レスポンスのキャッシュが必要な場合は、障害を監視するための最大期間または正確な期間を設定します(可能な場合)。
    • 適切な有効期限を設定して、障害が継続するとみられる期間よりも長くエラー レスポンスがキャッシュに保存されないようにします。
    • <ExcludeErrorResponse> 要素を使用せずに ResponseCache ポリシーを使用して、エラー レスポンスをキャッシュに保存します。

    この操作は、バックエンド サーバーの障害が短時間または一時的なものでないことが明らかな場合にのみ行ってください。

  • Apigee では、バックエンド サーバーからの 5xx レスポンスをキャッシュに保存することはおすすめしません。