Nginx принудительно перепроверяет устаревший кэш после тайм-аута

Nginx принудительно перепроверяет устаревший кэш после тайм-аута

При использовании кэша обратного прокси-сервера Nginx наблюдается случай, когда:

proxy_cache_background_update on;
proxy_cache_use_stale updating;

Если для того же URL-адреса от вышестоящего сервера приходит один ответ с max-age, а все остальные ответы не кэшируются, Nginx никогда не сможет восстановиться из этой ситуации.

Представьте себе такой сценарий:

  1. Клиент -> Nginx (MISS) -> Upstream200(Управление кэшем: без кэша)
  2. Клиент -> Nginx (MISS) -> Upstream200(Управление кэшем: без кэша)
  3. Клиент -> Nginx (MISS) -> Upstream200(Управление кэшем: без кэша)
  4. Клиент -> Nginx (MISS) -> Upstream503(Управление кэшем: максимальный возраст=10)
  5. Клиент -> Nginx (HIT,503, Возраст: 3)
  6. Клиент -> Nginx (HIT,503, Возраст: 8)
  7. Клиент -> Nginx (УСТАРЕВШИЙ,503, Возраст: 13) ->БГВверх по течению200 (Управление кэшем: без кэша)
  8. Клиент -> Nginx (УСТАРЕВШИЙ,503, Возраст: 18) ->БГВверх по течению200 (Управление кэшем: без кэша)
  9. Клиент -> Nginx (УСТАРЕВШИЙ,503, Возраст: 23) ->БГВверх по течению200 (Управление кэшем: без кэша)
  10. ... Клиент видит503навечно

В приведенном выше сценарии ошибка произошла в upstream один раз и вернула max-age (к сожалению, это поведение нельзя изменить). Поскольку реальный ответ 200 — это no-cache, он никогда не сможетперезаписатьSTALE 503 и навсегда выдает ошибку, пока не будет удалена вручную.

Ничего не нашел в сети по этому сценарию, поэтому спрашиваю. Как с этим бороться? Я используюOpenRestyпоэтому мне доступны как модули Nginx с открытым исходным кодом, так и Lua.

Возможные решения и мои исследования:

  • stale-if-errorи stale-while-revalidateрасширения заголовка Cache-Control, похоже, решают эту проблему. К сожалению, заголовки upstream не открыты для изменения (и нет способа взломать их до того, как Nginx обработает заголовки, как и ожидалось).

  • Использование скрипта Lua для ручной установки таймаута для STALE кэшей и очистки при его превышении. Но я бы предпочел использовать решение, если его предоставляет standard/Nginx.

  • Добавьте второй обратный прокси-сервер для добавления заголовков stale-if-errorи stale-while-revalidateпо умолчанию (я бы лучше позволил проблеме существовать, чем делать это).

  • Используйте Lua для отслеживания возраста кэша, затем установите переменную true, если она превышена, а затем используйте ее из proxy_cache_bypassNginx. (Немного серая область, порядок выполнения будет иметь значение с директивами фазы содержимого)

Связанный контент