Nginx: ускорение сайта с помощью кеширования

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

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

Данная информация предназначена для услуг: VPS хостинг или Облачный хостинг

Что такое кеширование в Nginx и как оно работает?

Кеширование в Nginx — это процесс сохранения копий ответов от бэкенд-серверов (таких как PHP-FPM, Apache, Gunicorn, Node.js и др.) или статических файлов во временном хранилище (в оперативной памяти или на диске). Когда новый пользователь запрашивает тот же самый ресурс, Nginx отдает его из своего кеша, не обращаясь к бэкенду. Это позволяет:

  • Снизить нагрузку на бэкенд-сервер. Обработка PHP, Python или запросов к базе данных — ресурсоемкие операции. Кеширование минимизирует их количество.

  • Увеличить скорость отдачи контента. Отдача готового файла из памяти (RAM) или с быстрого SSD-диска происходит в разы быстрее, чем генерация страницы "с нуля".

  • Повысить устойчивость к высоким нагрузкам. Ваш сайт сможет выдерживать больше одновременных посетителей без потери производительности.

Базовый принцип работы:

  1. Первый запрос: Пользователь А запрашивает страницу /about-us/.

  2. Обращение к бэкенду: Nginx, не найдя эту страницу в своем кеше, передает запрос бэкенд-серверу (например, на php-fpm).

  3. Сохранение в кеш: Получив сгенерированный HTML-ответ, Nginx отдает его пользователю А и одновременно сохраняет копию в своем кеше, присваивая ей уникальный ключ (обычно на основе полного URL и параметров запроса).

  4. Последующие запросы: Пользователь Б запрашивает ту же страницу /about-us/.

  5. Отдача из кеша: 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/).


Стратегии инвалидации кеша (очистки)

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

  1. По времени (proxy_cache_validinactive): Самый простой способ. Подходит для контента, который меняется регулярно, но не критично, если пользователи увидят его с небольшой задержкой.

  2. По версии файла (для статики): Добавляйте версию в имена статических файлов (style.v2.css). При изменении файла его имя меняется, и браузер загружает новую версию.

  3. Принудительная очистка (Purge): Используйте модуль proxy_cache_purge. Ваше приложение (например, CMS при обновлении статьи) может отправлять запрос на http://example.com/purge/updated-page-url/, чтобы мгновенно удалить устаревшую страницу из кеша.

  4. "Умный" ключ кеша: Можно настроить 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 для мониторинга и постепенно усложняйте конфигурацию, подстраивая ее под логику вашего приложения.

  • 0 Пользователи нашли это полезным

Помог ли вам данный ответ?

Ищете что-то другое?

xvps.ru