Cache-Control и кеширование в NGINX: практическое руководство

Быстрые ссылки
Как работает кеширование?
Как использовать Cache-Control в NGINX
Surrogate-Control для управления поведением CDN
Как работает кеширование
Кеширование — это сохранение скачанных данных для повторного использования без обращения к серверу. У каждого пользователя в браузере есть локальный кеш, который хранит статические объекты (CSS, JS, изображения). При следующем заходе браузер может загрузить ресурс из кеша, если он ещё действителен, что уменьшает время загрузки и снижает нагрузку на веб‑сервер.
На стороне сервера часто используется CDN (Content Delivery Network). CDN располагает копиями ваших страниц и ресурсов на множестве edge‑серверов по всему миру. CDN уменьшает латентность и нагрузку на ваш origin‑сервер. Многие CDN уважают заголовки Cache-Control и Surrogate-Control, но поведение конкретного провайдера стоит проверять в документации.
Заголовок Cache-Control позволяет задать, какие ресурсы и на сколько времени могут храниться в кеше. Перед массовым применением важно понять исключения:
- Не кешируйте персональные страницы, где отображается личная информация пользователя, через общие CDN. Иначе один пользователь может увидеть данные другого.
- Для страниц, уникальных для каждого пользователя, используйте Cache-Control: private — тогда кеширует только браузер пользователя.
- Статические файлы (изображения, CSS, JS) обычно безопасно кешировать долгое время.
TTL (Time To Live) определяет, как долго ресурс остаётся валидным. Баланс между длинным TTL и быстрой доставкой обновлений — ключевой. Для главной страницы имеет смысл ставить небольшие значения (несколько минут), для статических артефактов — годы. Чтобы обновлять статические ресурсы без инвалидирования CDN, применяйте версионирование имён файлов (например, styles-1.0.1.css).
Cache-Control: базовые директивы и смысл
Ниже — наиболее употребительные значения Cache-Control и краткие рекомендации.
- public — ресурс может кешироваться любым кешем (браузеры, CDN). Применяйте для большинства статических ресурсов.
- private — ресурс содержит данные, которые не должны кешироваться общими прокси/CDN; браузер может кешировать локально. Используйте для приватных/аутентифицированных страниц.
- no-cache — странное название: кеширование не запрещено, но перед использованием кешированный ресурс должен быть пере-проверен у origin (revalidation). Применяйте, если требуется частая валидация.
- no-store — отключает кеширование полностью. Используйте для сверхчувствительных данных (например, платежные страницы), где хранение ответа недопустимо.
Дополнительно часто используют директивы:
- max-age=SECONDS — время жизни в секундах.
- must-revalidate — требовать повторной проверки после истечения max-age.
- s-maxage — специфично для shared caches (CDN); переопределяет max-age для прокси.
- no-transform — запрещает преобразования ответа (например, сжатие/оптимизацию изображений) промежуточными узлами.
Примеры значений таймингов: 30s (30 секунд), 1m (1 минута), 24h (24 часа), 3d (3 дня), 1M (1 месяц), 2y (2 года). В NGINX эти обозначения поддерживаются в директиве expires.
Как использовать Cache-Control в NGINX
NGINX позволяет задавать заголовки и директиву expires. Общий пример:
expires 1y;
add_header Cache-Control "public, no-transform";Первая строка задаёт max-age на 1 год (через директиву expires), вторая — явный заголовок Cache-Control.
Лучше применять настройки через location‑блоки, чтобы разные типы файлов имели разные TTL:
location ~* .(?:css|js)$ {
expires 1y;
add_header Cache-Control "public";
}Регулярные выражения (параметр ~*) помогают задать общие правила для типов контента. Для отдельных путей используйте обычный location, он имеет приоритет над regex:
location /profile {
expires 2d;
add_header Cache-Control "public, no-transform";
}Для точного совпадения пути можно использовать модификатор =, который будет иметь более высокий приоритет:
location = /exact/path {
expires 30s;
add_header Cache-Control "private, no-cache";
}NGINX также поддерживает специальные значения expires, которые удобно знать:
- -1 или off — кеширование выключено и существующие заголовки не меняются.
- epoch — устанавливает Unix time zero, что явно отключает кеширование и может очистить кэши при использовании NGINX как reverse proxy.
- max — «истекает в конце вселенной», в оригинале: 31 декабря 2037.
Примечание: в конфигурационных примерах сохранены синтаксис и ключевые слова — при переводе на локальный язык описания ниже, в конфиге используйте точные английские ключевые слова, как в примерах.
Surrogate-Control для управления CDN
Surrogate-Control — заголовок, ориентированный на CDN/прокси, работает аналогично Cache-Control, но применяется только промежуточными кешами (например, Fastly, Varnish). Это удобно, если вы хотите, чтобы CDN кешировал ресурс дольше, чем браузер, или наоборот.
Пример настройки заголовков в NGINX:
add_header Surrogate-Control "public, max-age=86400";
add_header Cache-Control "public, max-age=120";В этом примере CDN может кешировать на 86400 секунд (1 день), а браузер — на 120 секунд. Всегда тестируйте с конкретным CDN: поддержка Surrogate-Control у разных провайдеров различается.
Важно: при использовании add_header учитывайте контекст (server, location) и директивы вроде add_header … always, если хотите добавлять заголовки при любых ответах.
Лучшие практики и методология принятия решений
Короткая методика настройки кеширования для сайта:
- Разбейте ресурсы на категории: статические неизменные (изображения, шрифты), статические версионируемые (CSS/JS), динамические общие (главная), персонализированные (профиль, корзина).
- Определите политику для каждой категории:
- Статические неизменные: expires 1y; Cache-Control: public, immutable
- Статические версионируемые: expires 1y; Cache-Control: public
- Динамические общие: expires 60–300s; Cache-Control: public, must-revalidate
- Персонализированные: expires 0; Cache-Control: private, no-store / no-cache
- Реализуйте версионирование для статических файлов (content hashing или включение версии в имя).
- Настройте Surrogate-Control для CDN при необходимости (более долгий TTL для CDN, короткий — для браузера).
- Тестируйте: curl с разными заголовками, инструменты CDN, браузерные DevTools.
- Планируйте инвалидации и rollout: используйте ручную инвалидацию CDN для экстренных обновлений.
Мини‑чеклист для развертывания кеширования:
- Версионирование статических файлов внедрено.
- Для каждого типа ресурса задана политика TTL.
- Для приватного контента установлен Cache-Control: private/no-store.
- Проверена поддержка Surrogate-Control у CDN.
- Разработан процесс инвалидации (автоматический или ручной).
Шпаргалка и конфиг‑сниппеты
Простейшие конфиги для NGINX:
- Кешировать CSS и JS на год:
location ~* .(?:css|js)$ {
expires 1y;
add_header Cache-Control "public";
}- Короткий TTL для главной страницы:
location = / {
expires 5m;
add_header Cache-Control "public, must-revalidate";
}- Приватный контент:
location /account {
expires off;
add_header Cache-Control "private, no-store";
}- Surrogate-Control для CDN и короткий TTL для браузера:
add_header Surrogate-Control "public, max-age=86400";
add_header Cache-Control "public, max-age=120";Когда кеширование может подвести или не сработать
- CDN не уважает Surrogate-Control — некоторые провайдеры игнорируют этот заголовок. Всегда проверяйте в документации или тестируйте в реальных условиях.
- Неправильные директивы приводят к утечке персональных данных: если страницу с личными данными пометили public, CDN может отдать её другим пользователям.
- Долгий TTL и отсутствие версионирования убирают возможность быстро выкатывать исправления; помните про стратегию инвалидации.
- Промежуточные прокси или корпоративные кеши могут модифицировать заголовки. Контролируйте поведение через логирование и тесты.
Альтернативы и дополнения к Cache-Control
- ETag и Last-Modified — позволяют серверу отдавать 304 Not Modified при совпадении, экономя трафик. Они работают вместе с Cache-Control.
- Service Worker — для более тонкого клиентского кеширования и оффлайн‑режима; даёт полный контроль над стратегией загрузки.
- Принудительные CDN‑инвалидации — полезно при катастрофических релизах, когда нужно немедленно убрать старые версии.
Мини‑сценарии тестирования и критерии приёмки
Тесты, которые стоит выполнить перед выходом в прод:
- Проверка заголовков curl:
curl -I https://example.com/styles-1.0.1.cssОжидается: Cache-Control: public при желаемом max-age и/или Surrogate-Control если настроен.
- Поведение CDN: изменение файла с новым именем должно привести к получению новой версии без ручной инвалидации.
- Тест приватности: убедитесь, что страницы с авторизацией не кешируются на CDN и не доступны без авторизации.
Критерии приёмки:
- Для статических ресурсов задан TTL ≥ 1 месяц и включено версионирование.
- Для персональных страниц — Cache-Control: private/no-store и отсутствие CDN‑кеша.
- Surrogate-Control настроен и подтверждён тестом с CDN (если используется).
Роль‑ориентированные контрольные списки
Для разработчика:
- Настроить версионирование активов.
- Внедрить конфиги NGINX для основных типов ресурсов.
- Написать тесты на заголовки.
Для девопса:
- Проверить поведение CDN и логи.
- Настроить автоматические/ручные инвалидации.
- Обеспечить мониторинг 4xx/5xx после изменения кеш‑политик.
Для фронтенда:
- Убедиться, что критические ресурсы обновляются при релизах.
- Использовать immutable для неизменяемых ассетов.
Фактбокс — ключевые числа и понятия
- TTL: задаётся в секундах в max-age; в NGINX часто задают через expires (1y, 1M, 24h и т. п.).
- Surrogate-Control: используется для CDN, может переопределять поведение shared cache.
- no-store: полностью запрещает хранение ответа.
- private: разрешает хранение только в локальном браузере.
Короткий глоссарий
- TTL — время жизни кеша (Time To Live).
- CDN — сеть доставки контента (Content Delivery Network).
- Origin — ваш основной веб‑сервер, источник контента.
- Invalidate — операция удаления/очистки кеша на CDN.
Decision flowchart
flowchart TD
A[Начало: нужно ли кешировать ресурс?] --> B{Ресурс персональный?}
B -- Да --> C[Cache-Control: private или no-store]
B -- Нет --> D{Статический файл с версией?}
D -- Да --> E[Cache-Control: public, expires 1y]
D -- Нет --> F{Часто обновляется?}
F -- Да --> G[Cache-Control: public, max-age=60-300, must-revalidate]
F -- Нет --> E
E --> H[Рассмотреть Surrogate-Control для CDN]
G --> H
C --> H
H --> I[Тестирование и мониторинг]Заключение
Кеширование — мощный инструмент для ускорения сайта и снижения нагрузки на сервер. Правильно разделяйте ресурсы по категориям, применяйте соответствующие заголовки Cache-Control и, при необходимости, Surrogate-Control для CDN. Внедряйте версионирование, тестируйте конфигурации и имейте план инвалидации на случай срочных изменений.
Важно: всегда проверяйте, как ваш конкретный CDN и инфраструктура обрабатывают заголовки, и не забывайте о безопасности персональных данных.
Примечание: примеры конфигураций и директив в статье написаны в форме, пригодной для копирования в NGINX — используйте их как стартовую точку и адаптируйте под вашу архитектуру.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента