Nginx proxy_cache: очистка кэша прокси-сервера | AdminWiki

Nginx proxy_cache: очистка кэша прокси-сервера

21 августа 2026 7 мин. чтения
Содержание статьи

Введение: зачем управлять кэшем proxy_cache

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

Решение - управляемая инвалидация кэша. Есть три основных подхода: полная очистка всей кэш-директории, выборочная очистка через purge-зону с модулем ngx_cache_purge и автоматическая инвалидация при обновлении данных. В этой статье разобраны все три метода с рабочими конфигурациями, командами и предупреждениями о рисках.

Для базовой настройки кэширования рекомендую сначала изучить полное руководство по proxy_cache, а для точечной очистки по URL и regex - материал по ngx_cache_purge.

Основы proxy_cache: где хранится кэш и как им управлять

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

Директива proxy_cache_path: параметры и пример

Директива proxy_cache_path задаёт путь к файлам кэша, структуру каталогов, размер зоны ключей и лимиты хранения. Базовая конфигурация:

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

Разбор параметров:

  • /var/cache/nginx - корневая директория кэша. Именно здесь Nginx создаёт файлы с ответами бэкенда.
  • levels=1:2 - иерархия подкаталогов. Первый уровень - один символ, второй - два символа. Это ускоряет поиск файлов на файловой системе при большом количестве записей.
  • keys_zone=my_cache:10m - имя зоны и размер разделяемой памяти для хранения ключей и метаданных. Зона в 10 МБ хранит примерно 80 000 ключей.
  • max_size=1g - максимальный суммарный размер кэша. При превышении Nginx запускает фоновый процесс удаления наименее используемых данных.
  • inactive=60m - время неактивности записи. Если файл не запрашивали 60 минут, он удаляется из кэша независимо от max_size.
  • use_temp_path=off - запись временного файла сразу в целевую директорию, без промежуточного копирования. Снижает нагрузку на диск.

Разница между max_size и inactive принципиальна: первый ограничивает объём, второй - возраст. Запись может быть удалена по любому из этих условий, что сработает раньше.

Формирование ключа кэша: proxy_cache_key

Ключ кэша определяет, как Nginx сопоставляет запрос с сохранённым ответом. По умолчанию ключ выглядит так:

proxy_cache_key $scheme$proxy_host$request_uri;

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

proxy_cache_key "$scheme$request_method$host$request_uri";

Для purge-запросов ключ критичен: вы должны точно воспроизвести его, чтобы удалить нужную запись. Если ключ формируется из переменных, purge-запрос должен использовать те же переменные в том же порядке.

Полная очистка кэша: простой и радикальный метод

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

Безопасная очистка: остановка Nginx и удаление файлов

Если удалить файлы кэша во время работы Nginx, процесс может продолжать держать открытые дескрипторы удалённых файлов. Новые запросы создадут новые файлы, но старые дескрипторы останутся в памяти до перезапуска. В некоторых случаях это приводит к ошибкам 502, когда Nginx пытается прочитать удалённый файл. Безопасная последовательность:

systemctl stop nginx
rm -rf /var/cache/nginx/*
systemctl start nginx

После запуска проверьте, что кэш пуст и сервер отвечает:

ls -la /var/cache/nginx/
curl -I http://localhost/

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

Очистка без остановки: использование find и других инструментов

Когда остановка сервиса недопустима, можно удалить файлы через find:

find /var/cache/nginx -type f -delete

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

Более безопасная альтернатива - автоматизация очистки через cron с предварительной проверкой состояния Nginx.

Выборочная очистка кэша: настройка purge-зоны

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

Установка и настройка модуля ngx_cache_purge

Модуль ngx_cache_purge не входит в стандартную сборку Nginx. В Debian и Ubuntu он доступен в пакете nginx-extras:

apt update
apt install nginx-extras

В CentOS/RHEL модуль может потребовать компиляции из исходников с параметром --add-module=/path/to/ngx_cache_purge. После установки проверьте, что модуль загружен:

nginx -V 2>&1 | grep -o ngx_cache_purge

Если вывод пустой, модуль не установлен, и директива proxy_cache_purge вызовет ошибку конфигурации.

Конфигурация purge-зоны и примеры запросов

Полный пример конфигурации с purge-зоной:

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

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;
        proxy_cache my_cache;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
    }

    location ~ /purge(/.*) {
        allow 127.0.0.1;
        deny all;
        proxy_cache_purge my_cache $scheme$request_method$host$1;
    }
}

Запрос на очистку конкретного URL:

curl -X PURGE http://example.com/purge/api/users/123

Обратите внимание: путь в purge-запросе должен соответствовать пути в ключе кэша. Если ключ формируется как $scheme$request_method$host$request_uri, то для URL /api/users/123 purge-запрос должен идти на /purge/api/users/123.

Директивы allow и deny ограничивают доступ к purge-зоне. Без них любой внешний клиент сможет очищать кэш, что создаёт риск DoS-атаки: злоумышленник отправляет множество PURGE-запросов, кэш постоянно пустует, бэкенд перегружается.

Автоматическая инвалидация кэша при обновлении данных

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

Интеграция purge в CI/CD pipeline

Добавьте шаг в pipeline после деплоя приложения. Пример для GitLab CI:

invalidate_cache:
  stage: deploy
  script:
    - curl -X PURGE http://nginx-server/purge/api/users
    - curl -X PURGE http://nginx-server/purge/api/products
  only:
    - main

Важно: purge-зона должна быть доступна из сети CI/CD. Если вы ограничили доступ через allow 127.0.0.1, добавьте IP runner'а или используйте SSH-туннель.

Использование заголовков от бэкенда для инвалидации

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

location / {
    proxy_pass http://backend;
    proxy_cache my_cache;
    proxy_cache_bypass $http_x_cache_purge;
    proxy_no_cache $http_x_cache_purge;
}

Когда бэкенд возвращает заголовок X-Cache-Purge: 1, Nginx не сохраняет ответ в кэш и не использует кэшированную версию. Это полезно для ответов с ошибками или персонализированных данных. Ограничение: метод не удаляет уже существующие записи, он только предотвращает их создание и использование.

Практические примеры для типовых задач

Кейс 1: API-сервис с кэшированием ответов

Для API, где данные обновляются через POST/PUT/DELETE, настройте кэш только для GET-запросов и добавьте purge-зону:

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

server {
    listen 80;
    server_name api.example.com;

    location /api/ {
        proxy_pass http://backend;
        proxy_cache api_cache;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        proxy_cache_valid 200 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_methods GET HEAD;
    }

    location ~ /purge-api(/.*) {
        allow 127.0.0.1;
        deny all;
        proxy_cache_purge api_cache $scheme$request_method$host$1;
    }
}

При обновлении ресурса через POST отправляйте PURGE-запрос на соответствующий GET-URL. Например, после обновления пользователя с ID 123 выполните curl -X PURGE http://api.example.com/purge-api/api/users/123.

Кейс 2: Динамический сайт с кэшированием страниц

Для сайта с авторизацией кэшируйте только публичные страницы, а для авторизованных пользователей обходите кэш:

location / {
    proxy_pass http://backend;
    proxy_cache site_cache;
    proxy_cache_key "$scheme$request_method$host$request_uri";
    proxy_cache_valid 200 30m;
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
}

При изменении контента в CMS отправляйте PURGE-запрос на обновлённую страницу. Если CMS поддерживает вебхуки, настройте вызов curl -X PURGE http://example.com/purge/page-url при сохранении записи.

Кейс 3: Балансировка нагрузки с общим кэшем

При балансировке несколько Nginx могут использовать общий кэш на сетевом хранилище:

proxy_cache_path /mnt/shared-cache levels=1:2 keys_zone=shared_cache:10m max_size=10g inactive=120m use_temp_path=off;

Очистка выполняется на одном узле, но влияет на все, так как файлы общие. Убедитесь, что purge-запросы отправляются на один выделенный узел, чтобы избежать гонок при одновременной очистке с разных серверов. Для синхронизации можно использовать общий скрипт, который последовательно отправляет PURGE-запросы на каждый узел.

Для кэширования статики и изображений с интеграцией CDN подойдёт отдельное руководство.

Безопасность и предотвращение ошибок 502 при очистке кэша

Ошибка 502 Bad Gateway возникает, когда Nginx не может получить ответ от бэкенда. При очистке кэша это происходит по трём причинам: удаление файлов во время работы Nginx, перегрузка бэкенда после очистки и неправильная конфигурация purge-зоны.

Ограничение доступа к purge-зоне

Purge-зона должна быть доступна только из доверенной сети. Используйте комбинацию allow и deny:

location ~ /purge(/.*) {
    allow 10.0.0.0/8;
    allow 127.0.0.1;
    deny all;
    proxy_cache_purge my_cache $scheme$request_method$host$1;
}

Для дополнительной защиты добавьте basic-аутентификацию:

location ~ /purge(/.*) {
    auth_basic "Purge zone";
    auth_basic_user_file /etc/nginx/.htpasswd;
    allow 127.0.0.1;
    deny all;
    proxy_cache_purge my_cache $scheme$request_method$host$1;
}

Мониторинг и тестирование после очистки

После очистки проверьте, что Nginx отвечает корректно и кэш заполняется:

curl -I http://example.com/
tail -f /var/log/nginx/error.log

Для мониторинга состояния кэша включите stub_status:

location /nginx_status {
    stub_status;
    allow 127.0.0.1;
    deny all;
}

Запрос curl http://localhost/nginx_status покажет количество обращений к кэшу, попаданий и промахов. После очистки количество промахов временно вырастет - это ожидаемо.

Если вы используете облачную инфраструктуру для размещения Nginx, рассмотрите Timeweb Cloud с готовыми VDS и управляемым Kubernetes для масштабирования кэширующего слоя.

Заключение

Полная очистка через rm -rf проста, но требует остановки Nginx и создаёт всплеск нагрузки на бэкенд. Выборочная очистка через ngx_cache_purge гибче: она удаляет только нужные записи и не затрагивает остальной кэш. Автоматизация через CI/CD или заголовки бэкенда экономит время и снижает риск человеческой ошибки.

Выбирайте метод по задаче: для редких полных сбросов подойдёт ручная очистка, для частых обновлений - purge-зона, для регулярных деплоев - интеграция в pipeline. Тестируйте на staging, ограничивайте доступ к purge-зоне и мониторьте состояние бэкенда после очистки. Полное руководство по безопасной инвалидации кэша в production-среде доступно в отдельной статье.

Поделиться:
Сохранить гайд? В закладки браузера