nginx: как кэшировать только отрицательные ответы FastCGI
Нужен коллективный мозговой штурм:). Существует тяжелое PHP-приложение (например, Magento), и каждый раз, когда посетитель попадает на несуществующую страницу (или возникает проблема с определенной частью приложения, и он возвращает ошибки), нагрузка на сервер приложения становится снежной:
в случае несуществующих страниц они не кэшируются, и приложение тратит довольно много ресурсов, чтобы проверить все и сгенерировать кэшированную копию, что будет пустой тратой времени;
В случае проблем с частью приложения, приложение потратит драгоценное время на генерацию этих сообщений об ошибках за счет посетителей здоровых частей сайта.
Идея заключается в том, чтобы кэшировать все отрицательные ответы, такие как 404 и 5xx, поступающие от бэкэнда FastCGI на интерфейсе nginx, скажем, на 5 минут - это значительно снизит влияние на производительность серверов приложений.
Кэширование может быть довольно легко реализовано с помощью директив fastcgi_cache_*. Однако, как только вы определите директивы fastcgi_cache_* в блоке местоположения, где расположен fastcgi_pass, он попытается кэшировать все, что проходит через этот блок местоположения.
Следовательно, вопрос заключается в том, как ограничить fastcgi_cache, скажем, 404 ответами только из серверных сценариев?
Просто чтобы проиллюстрировать сценарий немного подробнее. Представьте, что запрос идет в /app/missing, у приложения есть единственная точка входа в /index.php, поэтому nginx передаст запрос на внутренний сервер FastCGI, вызвав /index.php/app/missing. Теперь, так как /app/ отсутствующий не существует, index.php вернет HTTP 404. Этот маршрут будет загружать процессор столько раз, сколько вы запросите /app/missing. Желательно, чтобы после возврата HTTP 404 из index.php файл /app/ отсутствующий кэшировался с получающейся страницей 404 из index.php в nginx, поэтому, если кто-то сразу же запрашивает /app/missing, вызов не выполняется. Бэкэнд PHP, но возвращается кешированная страница.
1 ответ
Это может сделать трюк:
fastcgi_cache_valid 200 301 302 0;
fastcgi_cache_valid 404 500 503 5m;
Если nginx не допускает 0 в качестве значения здесь, то вам нужно заставить приложение PHP добавить заголовок HTTP X-Accel-Expires: 0
к его выводу на допустимых страницах, а затем иметь эту строку в конфигурации nginx:
fastcgi_cache_valid 404 500 503 5m;