Скорость загрузки сайта — критически важный фактор, влияющий на пользовательский опыт, конверсию и ранжирование в поисковых системах. Одним из самых эффективных способов радикально повысить производительность веб-ресурса является кеширование. Если ваш сайт работает на сервере с веб-сервером Nginx, вы можете использовать его мощный встроенный механизм кеширования для разгрузки бэкенда и мгновенной отдачи контента пользователям.
В этой статье мы детально разберем, как настроить кеширование статического и динамического контента в Nginx. Вы узнаете о директивах, их назначении, оптимальных значениях и методах проверки работоспособности кеша.
Данная информация предназначена для услуг: VPS хостинг или Облачный хостинг
Что такое кеширование в Nginx и как оно работает?
Кеширование в Nginx — это процесс сохранения копий ответов от бэкенд-серверов (таких как PHP-FPM, Apache, Gunicorn, Node.js и др.) или статических файлов во временном хранилище (в оперативной памяти или на диске). Когда новый пользователь запрашивает тот же самый ресурс, Nginx отдает его из своего кеша, не обращаясь к бэкенду. Это позволяет:
-
Снизить нагрузку на бэкенд-сервер. Обработка PHP, Python или запросов к базе данных — ресурсоемкие операции. Кеширование минимизирует их количество.
-
Увеличить скорость отдачи контента. Отдача готового файла из памяти (RAM) или с быстрого SSD-диска происходит в разы быстрее, чем генерация страницы "с нуля".
-
Повысить устойчивость к высоким нагрузкам. Ваш сайт сможет выдерживать больше одновременных посетителей без потери производительности.
Базовый принцип работы:
-
Первый запрос: Пользователь
Азапрашивает страницу/about-us/. -
Обращение к бэкенду: Nginx, не найдя эту страницу в своем кеше, передает запрос бэкенд-серверу (например, на
php-fpm). -
Сохранение в кеш: Получив сгенерированный HTML-ответ, Nginx отдает его пользователю
Аи одновременно сохраняет копию в своем кеше, присваивая ей уникальный ключ (обычно на основе полного URL и параметров запроса). -
Последующие запросы: Пользователь
Бзапрашивает ту же страницу/about-us/. -
Отдача из кеша: Nginx проверяет свой кеш, находит валидную (не устаревшую) копию и мгновенно отдает ее пользователю
Б, без какого-либо обращения к бэкенду.
Настройка кеширования статического контента
Статический контент — это файлы, которые не меняются при каждом запросе: изображения (JPEG, PNG, SVG), таблицы стилей (CSS), клиентские скрипты (JavaScript), шрифты, PDF-файлы и другие медиафайлы. Их кеширование настраивается проще всего и дает мгновенный результат.
Базовая конфигурация в блоке server или location:server {
listen 80;
server_name example.com;
# Директива для кеширования статики
location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {
# Включает обработку заголовков Expires и Cache-Control
expires 1y;
add_header Cache-Control "public, immutable";
# Отключает логирование для статических файлов (опционально, для экономии ресурсов)
access_log off;
# Добавляет заголовок, информирующий о статусе кеша (для отладки)
add_header X-Cache-Status $upstream_cache_status;
}
}
Разберем ключевые директивы:
-
location ~* \.(jpg|jpeg|png|...)$– Блок, который обрабатывает все файлы с указанными расширениями. Модификатор~*означает регистронезависимое совпадение по регулярному выражению. -
expires 1y;– Устанавливает срок жизни кеша в браузере пользователя. В данном случае — 1 год. Браузер не будет повторно запрашивать этот файл в течение года. Другие значения:1d(день),1h(час),30m(30 минут). -
add_header Cache-Control "public, immutable";– Более современный и приоритетный аналогexpires.-
public– Указывает, что ресурс может быть закеширован любым кешем (браузером, CDN, прокси). -
immutable– Сообщает браузеру, что содержимое файла никогда не меняется. Это предотвращает лишние проверки актуальности, что особенно полезно для ресурсов с версиями в имени файла (например,style.v123.css).
-
Результат: После такой настройки браузеры ваших пользователей будут хранить статические файлы локально, что drastically сократит количество HTTP-запросов к вашему серверу и ускорит загрузку последующих страниц.
Настройка кеширования динамического контента (прокси-кеш)
Динамический контент — это страницы, которые генерируются скриптами: главная страница, записи блога, карточки товаров и т.д. Их кеширование сложнее, так как контент может меняться, но именно оно дает максимальный прирост производительности.
Конфигурация происходит в несколько этапов.
Шаг 1: Определение зоны кеша (вне блока server)
Директива proxy_cache_path определяет, где и как хранить кешированные файлы. Ее обычно размещают в основном конфигурационном файле nginx.conf внутри блока http.
http {
# ...
# Определение зоны кеша с именем 'my_cache'
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
# ...
}
Параметры директивы proxy_cache_path:
-
/var/cache/nginx– Путь на диске, где будут физически храниться файлы кеша. Убедитесь, что у пользователя, от которого работает Nginx (обычноnginxилиwww-data), есть права на запись в эту директорию. -
levels=1:2– Структура поддиректорий для хранения большого количества файлов. Рекомендуется для улучшения производительности файловой системы. -
keys_zone=my_cache:10m– Задает имя зоны (my_cache) и выделяет 10 МБ оперативной памяти для хранения метаданных (ключей) кеша. 1 МБ зоны может хранить ~8000 ключей. -
max_size=10g– Максимальный общий размер кеша на диске. При превышении этого значения Nginx удалит наименее востребованные файлы. -
inactive=60m– Время, в течение которого кешированный файл, к которому не было обращений, будет храниться. После этого он удаляется, даже если не устарел. -
use_temp_path=off– Рекомендуется установить вoff, чтобы избежать лишнего копирования файлов между временными и постоянными зонами, что повышает производительность.
Шаг 2: Настройка кеширования в виртуальном хосте
Теперь в конфигурации вашего сайта (в блоке server или location) нужно активировать созданную зону кеша.server {
listen 80;
server_name example.com;
# Директива для добавления заголовка о статусе кеша (очень полезно для отладки)
add_header X-Cache-Status $upstream_cache_status;
location / {
# Включаем использование зоны кеша 'my_cache' для этого location
proxy_cache my_cache;
# Ключ кеша. По умолчанию Nginx использует полный URL.
# Это стандартная настройка, но ее можно кастомизировать.
proxy_cache_key "$scheme$request_method$host$request_uri";
# Условия, при которых ответ будет закеширован.
# Кешируем ответы с кодом 200 и 302 на 10 минут, 404 на 1 минуту.
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
# Кешировать ответы, даже если у них есть заголовок 'Set-Cookie' (с осторожностью!)
proxy_ignore_headers Cache-Control Set-Cookie;
# Бэкенд-сервер, куда идут запросы, если кеша нет
proxy_pass http://backend;
}
# Локация для очистки кеша (Purge). Дополнительный модуль.
location ~ /purge(/.*) {
allow 127.0.0.1; # Разрешаем только с локального IP
allow 192.168.1.0/24; # И из локальной сети
deny all; # Запрещаем всем остальным
proxy_cache_purge my_cache "$scheme$request_method$host$1";
}
}
Разберем ключевые директивы для прокси-кеша:
-
proxy_cache my_cache;– Активирует кеширование для текущего блокаlocation, используя ранее объявленную зону. -
proxy_cache_key– Определяет, как формируется уникальный ключ для кешируемого объекта. Стандартная настройка учитывает схему (http/https), метод запроса (GET/POST), домен и URI. -
proxy_cache_valid– Указывает, сколько времени хранить в кеше ответы с определенными статус-кодами. Это "страховка" на случай, если бэкенд не прислал заголовковCache-ControlилиExpires. -
proxy_ignore_headers– Заставляет Nginx игнорировать определенные заголовки от бэкенда. Это критически важно, если ваше приложение (например, WordPress) по умолчанию отправляетCache-Control: no-cache, must-revalidateили устанавливает куки. Внимание: Используйте эту настройку осторожно, только если вы уверены в логике инвалидации кеша другими способами. -
add_header X-Cache-Status $upstream_cache_status;– Полезнейший заголовок для отладки. Он показывает статус кеша для каждого запроса:-
MISS– Ответ не найден в кеше, был запрошен у бэкенда. -
HIT– Ответ отдан из кеша. -
BYPASS– Кеш был проигнорирован (например, из-заproxy_cache_bypass). -
EXPIRED– Срок жизни кешированного ответа истек, был запрошен у бэкенда.
-
-
proxy_cache_purge– Директива из отдельного модуляngx_http_proxy_module(не всегда собран по умолчанию). Позволяет принудительно удалить объект из кеша по определенному ключу, отправив запрос на специальный URL (например,example.com/purge/about-us/).
Стратегии инвалидации кеша (очистки)
Кеширование бесполезно, если пользователи видят устаревший контент. Поэтому важно правильно его очищать.
-
По времени (
proxy_cache_valid,inactive): Самый простой способ. Подходит для контента, который меняется регулярно, но не критично, если пользователи увидят его с небольшой задержкой. -
По версии файла (для статики): Добавляйте версию в имена статических файлов (
style.v2.css). При изменении файла его имя меняется, и браузер загружает новую версию. -
Принудительная очистка (Purge): Используйте модуль
proxy_cache_purge. Ваше приложение (например, CMS при обновлении статьи) может отправлять запрос наhttp://example.com/purge/updated-page-url/, чтобы мгновенно удалить устаревшую страницу из кеша. -
"Умный" ключ кеша: Можно настроить
proxy_cache_keyтак, чтобы он включал, например, куку аутентификации, если пользователь залогинен, и не кешировал персональный контент.
Мониторинг и отладка кеширования
Проверка заголовка X-Cache-Status
Самый простой способ проверить, работает ли кеш — использовать инструменты разработчика в браузере (вкладка "Network") или утилиту curl.curl -I http://example.com/about-us/
В ответе вы должны увидеть заголовок X-Cache-Status: HIT или MISS.
Анализ кеш-зоны
Вы можете добавить отдельный location для получения базовой статистики по кешу (требует модуль ngx_http_api_module или сторонние инструменты).
Логирование
В лог-файл Nginx можно добавить переменную $upstream_cache_status, чтобы отслеживать поведение кеша для всех запросов.log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$upstream_cache_status"'; # Добавляем статус кеша
access_log /var/log/nginx/access.log main;
Готовый пример конфигурации для WordPress
Вот сбалансированная конфигурация для типичного сайта на WordPress, которая кеширует статику и динамику, но обходит кеш для админ-панели и авторизованных пользователей.# В http-блоке nginx.conf
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=wp_cache:50m max_size=1g inactive=60m use_temp_path=off;
# ...
}
# В server-блоке виртуального хоста
server {
server_name example.com;
root /var/www/example.com;
index index.php;
# Статическое кеширование
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2|ttf)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Обработка PHP-запросов с кешированием
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
# Динамическое кеширование
proxy_cache wp_cache;
proxy_cache_valid 200 302 1h;
proxy_cache_valid 404 5m;
# НЕ кешируем запросы с определенными куками (авторизованные пользователи, админка)
# А также POST, PUT, DELETE запросы.
set $skip_cache 0;
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }
if ($request_uri ~* "/wp-admin/|/wp-login.php") { set $skip_cache 1; }
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass") {
set $skip_cache 1;
}
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
add_header X-Cache-Status $upstream_cache_status;
}
}Заключение
Грамотная настройка кеширования в Nginx — это не опция, а необходимость для любого современного, быстрого и отзывчивого сайта. Начиная с кеширования статики и заканчивая сложными конфигурациями прокси-кеша для динамических приложений, вы можете достичь многократного увеличения производительности и снижения нагрузки на сервер.
Помните: настройка кеширования — это итеративный процесс. Начните с базовых параметров, тщательно тестируйте, используйте заголовок X-Cache-Status для мониторинга и постепенно усложняйте конфигурацию, подстраивая ее под логику вашего приложения.