Базовое кэширование с Nginx: Улучшение времени отклика

Настройте безопасное базовое прокси-кэширование Nginx с зонами кэша, TTL, правилами обхода, заголовками статуса и шагами тестирования.

Базовое кэширование с Nginx: Улучшение времени отклика

Базовое кэширование с Nginx может улучшить время отклика, сохраняя копию ответов вышестоящего сервера и обслуживая их снова без обращения к приложению каждый раз. При осторожном использовании кэширование снижает нагрузку на бэкенд, сглаживает пики трафика и ускоряет повторные запросы.

Кэширование полезно не только для крупных сайтов. Даже небольшое приложение может выиграть, когда страницы, ответы API или статические файлы запрашиваются часто и не меняются каждую секунду.

Что Nginx может кэшировать

Nginx может кэшировать ответы от вышестоящего сервера, когда он действует как обратный прокси. Это отличается от обычного браузерного кэширования. Браузерное кэширование хранит файлы на устройстве пользователя. Прокси-кэширование Nginx хранит ответы на сервере, чтобы многие пользователи могли воспользоваться одной и той же кэшированной копией.

Простая настройка прокси-кэша состоит из двух частей. Сначала определите зону кэша в блоке http:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:10m
    max_size=1g inactive=60m use_temp_path=off;

Затем включите этот кэш в блоке server или location:

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_cache app_cache;
    proxy_cache_valid 200 10m;
    proxy_cache_valid 404 1m;
    add_header X-Cache-Status $upstream_cache_status;
}

Директива proxy_cache_path создает область хранения кэша. keys_zone определяет разделяемую память для ключей кэша и метаданных. max_size ограничивает использование диска. inactive удаляет элементы, к которым не было обращений в течение некоторого времени.

Директивы proxy_cache_valid определяют, как долго определенные коды ответа остаются в кэше. В примере успешные ответы кэшируются на 10 минут, а ответы 404 — на 1 минуту.

Заголовок X-Cache-Status полезен во время тестирования. Он может показывать такие значения, как MISS, HIT, BYPASS или EXPIRED, в зависимости от ситуации.

Для сайтов, которые также используют Nginx в качестве обратного прокси, это хорошо сочетается с настройкой обратного прокси.

Решение, что следует кэшировать

Самая сложная часть кэширования Nginx — не написание директив. Это решение, какой контент безопасно использовать повторно.

Хорошие кандидаты для кэширования включают:

  • Публичные маркетинговые страницы.
  • Публичные страницы документации.
  • Страницы со списками продуктов, которые обновляются по предсказуемому расписанию.
  • Анонимные ответы API.
  • Дорогие ответы вышестоящего сервера, которые одинаковы для многих пользователей.

Плохие кандидаты для кэширования включают:

  • Страницы аккаунтов.
  • Корзины покупок.
  • Административные экраны.
  • Ответы, содержащие личные данные пользователя.
  • Страницы, которые меняются в зависимости от cookies или заголовков авторизации.

Если ответ различается для каждого пользователя, не кэшируйте его, если у вас нет очень четкой стратегии ключей кэша. Случайная передача личного ответа одного пользователя другому — серьезная ошибка.

Вы можете обойти кэширование, когда запросы содержат данные сессии или авторизации:

proxy_cache_bypass $http_authorization;
proxy_no_cache $http_authorization;

Для сессий на основе cookies можно использовать аналогичный шаблон:

proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;

Точное имя cookie зависит от вашего приложения. Не копируйте это вслепую, не проверив, как ваше приложение обрабатывает сессии.

Практический сценарий: ваша публичная домашняя страница блога генерируется приложением и занимает 300 миллисекунд в загруженный день. Если вы кэшируете эту страницу на 5 минут, большинство посетителей быстро получают кэшированную копию, и приложение регенерирует её лишь изредка. Это хороший вариант использования, потому что домашняя страница публична и не зависит от пользователя.

Ключи кэша, заголовки и очистка

Nginx использует ключ кэша, чтобы решить, должны ли два запроса использовать один и тот же кэшированный ответ. Ключ кэша по умолчанию обычно основан на схеме, методе, хосте и URI. Для многих сайтов этого достаточно.

Если строки запроса меняют ответ, убедитесь, что они являются частью ключа. Если строки запроса являются только параметрами отслеживания, возможно, вы захотите нормализовать их на уровне приложения или CDN, а не позволять каждому utm_source создавать отдельную запись в кэше.

Заголовки кэша вышестоящего сервера также важны. Ваше приложение может отправлять такие заголовки, как:

Cache-Control: public, max-age=600

или:

Cache-Control: private, no-store

Nginx можно настроить на уважение или переопределение этих заголовков, но вы должны выбрать одну четкую политику. Если разработчики приложения ожидают, что Cache-Control: no-store предотвратит кэширование, переопределение этого поведения в Nginx может привести к запутанным и рискованным результатам.

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

Короткие TTL часто достаточны. 60-секундный кэш на загруженной конечной точке все еще может снять огромный объем трафика с бэкенда, сохраняя контент достаточно свежим.

Тестирование поведения кэша

После включения кэширования запросите один и тот же URL несколько раз и проверьте заголовки ответа:

curl -I https://example.com/

Если вы добавили X-Cache-Status, первый запрос может показать MISS, а последующие запросы должны показывать HIT. Если каждый запрос — MISS, проверьте заголовки ответа, правила обхода кэша, cookies запроса и доступность каталога кэша для записи рабочим процессом Nginx.

Также протестируйте поведение для авторизованных и неавторизованных пользователей. Именно здесь проявляются многие ошибки кэширования. Откройте окно приватного браузера, войдите как тестовый пользователь и убедитесь, что приватные страницы не кэшируются публично.

Следите за использованием диска. Кэш без практического ограничения может заполнить файловую систему. Используйте max_size, по возможности храните кэш отдельно от критических системных разделов и настройте оповещения о заполнении диска.

Когда обращаться за помощью

Привлеките опытного инженера Nginx или платформы, если кэшированный контент появляется под чужим пользователем, если процент попаданий в кэш остается низким после настройки или если файлы кэша неожиданно заполняют диск. Проблемы с кэшированием могут выглядеть просто, скрывая специфическое поведение приложения.

Вам также следует обратиться за помощью перед кэшированием аутентифицированных API, многопользовательских панелей управления или платежных потоков. Эти области требуют тщательного проектирования.

Базовое кэширование с Nginx работает лучше всего, когда вы начинаете с публичных, повторяемых ответов и коротких сроков жизни кэша. Добавляйте видимые заголовки статуса кэша во время тестирования, уважайте границы приватного контента и измеряйте как время отклика, так и нагрузку на бэкенд. При правильном подходе кэширование дает пользователям более быстрые страницы, давая вашему приложению возможность дышать.