
При использовании кэша обратного прокси-сервера Nginx наблюдается случай, когда:
proxy_cache_background_update on;
proxy_cache_use_stale updating;
Если для того же URL-адреса от вышестоящего сервера приходит один ответ с max-age, а все остальные ответы не кэшируются, Nginx никогда не сможет восстановиться из этой ситуации.
Представьте себе такой сценарий:
- Клиент -> Nginx (MISS) -> Upstream200(Управление кэшем: без кэша)
- Клиент -> Nginx (MISS) -> Upstream200(Управление кэшем: без кэша)
- Клиент -> Nginx (MISS) -> Upstream200(Управление кэшем: без кэша)
- Клиент -> Nginx (MISS) -> Upstream503(Управление кэшем: максимальный возраст=10)
- Клиент -> Nginx (HIT,503, Возраст: 3)
- Клиент -> Nginx (HIT,503, Возраст: 8)
- Клиент -> Nginx (УСТАРЕВШИЙ,503, Возраст: 13) ->БГВверх по течению200 (Управление кэшем: без кэша)
- Клиент -> Nginx (УСТАРЕВШИЙ,503, Возраст: 18) ->БГВверх по течению200 (Управление кэшем: без кэша)
- Клиент -> Nginx (УСТАРЕВШИЙ,503, Возраст: 23) ->БГВверх по течению200 (Управление кэшем: без кэша)
- ... Клиент видит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_bypass
Nginx. (Немного серая область, порядок выполнения будет иметь значение с директивами фазы содержимого)