Nginx はタイムアウト後に古いキャッシュを強制的に再検証します

Nginx はタイムアウト後に古いキャッシュを強制的に再検証します

Nginx リバース プロキシ キャッシュの使用時には、次のようなケースがあります。

proxy_cache_background_update on;
proxy_cache_use_stale updating;

同じ URL に対して、アップストリームから max-age 付きの応答が 1 つだけ送信され、他のすべての応答が no-cache の場合、Nginx はこの状況から回復することはできません。

次のシナリオを想像してください。

  1. クライアント -> Nginx (MISS) -> アップストリーム200(キャッシュ制御: キャッシュなし)
  2. クライアント -> Nginx (MISS) -> アップストリーム200(キャッシュ制御: キャッシュなし)
  3. クライアント -> Nginx (MISS) -> アップストリーム200(キャッシュ制御: キャッシュなし)
  4. クライアント -> Nginx (MISS) -> アップストリーム503(キャッシュ制御: max-age=10)
  5. クライアント -> Nginx (HIT、503、年齢:3)
  6. クライアント -> Nginx (HIT、503、年齢:8)
  7. クライアント -> Nginx (STALE、503、年齢:13) ->BG上流の200 (キャッシュ制御: キャッシュなし)
  8. クライアント -> Nginx (STALE、503、年齢:18) ->BG上流の200 (キャッシュ制御: キャッシュなし)
  9. クライアント -> Nginx (STALE、503、年齢:23) ->BG上流の200 (キャッシュ制御: キャッシュなし)
  10. ...クライアントは見る503永遠に

上記のシナリオでは、上流で一度エラーが発生し、max-ageが返されました(残念ながらこの動作は介入できません)。実際の200応答はno-cacheであるため、上書きするSTALE 503 は、手動で消去されるまで永久にエラーが発生します。

このシナリオについてウェブ上で何も見つけられなかったので、ここで質問します。これに対処する方法。私はオープンレスティそのため、Nginx オープンソース モジュールと Lua の両方にアクセスできます。

考えられる解決策と私の調査:

  • stale-if-errorCache-Control ヘッダーの拡張により、stale-while-revalidateこの問題は解決されるようです。残念ながら、アップストリーム ヘッダーは変更できません (また、予想どおり、Nginx がヘッダーを処理する前に、これらをハックして挿入する方法はありません)。

  • Lua スクリプトを使用して、STALE キャッシュのタイムアウトを手動で設定し、タイムアウトを超えたら消去します。ただし、標準/Nginx でソリューションが提供されている場合は、そのソリューションを使用する方がはるかに望ましいです。

  • ヘッダーを追加するために 2 番目のリバース プロキシをデフォルトで追加しますstale-if-error(stale-while-revalidateこれを行うよりも、問題をそのままにしておく方がよいでしょう)。

  • Lua を使用してキャッシュの経過時間を追跡し、経過時間を超えた場合は変数を true に設定して、proxy_cache_bypassNginx から使用します。(少しグレーな領域ですが、コンテンツ フェーズ ディレクティブでは実行順序が重要になります)

関連情報