Кэш FastCGI в Nginx сохраняет ответы PHP-приложений и других динамических бэкендов в виде статических файлов на диске. Это снижает нагрузку на PHP-FPM и ускоряет отдачу страниц. Проблема возникает, когда контент обновляется: Nginx продолжает отдавать устаревшую версию, пока кэш не будет инвалидирован. В этой статье разобраны два рабочих подхода: точечная очистка через модуль ngx_cache_purge и массовая очистка скриптами с контролем нагрузки. Примеры адаптированы под WordPress, PHP-FPM и другие CMS.
Как работает кэш FastCGI в Nginx и зачем его очищать
Nginx формирует ключ кэша из набора переменных. По умолчанию это комбинация $scheme$request_method$host$request_uri. Каждый уникальный ключ соответствует одному файлу в зоне кэша, заданной директивой fastcgi_cache_path. Когда приходит запрос, Nginx вычисляет ключ и ищет файл на диске. Если файл найден и не истёк срок действия (fastcgi_cache_valid), ответ отдаётся из кэша без обращения к PHP-FPM.
Устаревший кэш приводит к тому, что посетители видят старую версию страницы: изменённый товар в каталоге, неактуальную статью, сброшенные комментарии. Поэтому очистка нужна сразу после публикации изменений. Полный сброс кэша решает проблему, но создаёт пиковую нагрузку на бэкенд: все страницы одновременно генерируются заново. Точечная инвалидация позволяет удалить только изменившиеся URL, сохранив остальной кэш нетронутым.
Для управления кэшем статики и изображений применяются отдельные механизмы, включая open_file_cache и stale-кэш. Подробнее об этом читайте в руководстве по кэшу статики и изображений в Nginx.
Точечная очистка кэша для конкретного URL с помощью ngx_cache_purge
Модуль ngx_cache_purge добавляет директиву fastcgi_cache_purge, которая удаляет кэш по заданному ключу. Это штатный способ инвалидации без удаления файлов вручную. Модуль не входит в стандартную сборку Nginx, поэтому его нужно подключать отдельно.
Установка и подключение модуля ngx_cache_purge
Проверьте, установлен ли модуль в вашей сборке:
nginx -V 2>&1 | grep -o ngx_cache_purge
Если вывод пустой, модуль отсутствует. Есть два пути установки. Первый - сборка Nginx из исходников с добавлением модуля:
./configure --add-module=/path/to/ngx_cache_purge
make && make install
Второй - использование готовых пакетов. В репозиториях Debian и Ubuntu пакет называется nginx-extras, в CentOS/RHEL - nginx-module-cache-purge из репозитория nginx.org. После установки проверьте версию ещё раз: строка --add-module=/path/to/ngx_cache_purge должна появиться в выводе nginx -V.
Пример конфигурации для очистки кэша WordPress
Базовая конфигурация для WordPress с FastCGI-кэшем и эндпоинтом очистки:
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
server {
listen 80;
server_name example.com;
set $no_cache 0;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_cache WORDPRESS;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 30m;
fastcgi_cache_bypass $no_cache;
}
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1$is_args$args";
}
}
Регулярное выражение /purge(/.*) захватывает часть URL после /purge. Переменная $1 содержит путь запрашиваемой страницы, а $is_args$args добавляет query-строку, если она есть. Ключ кэша в location очистки должен точно совпадать с ключом в location PHP. Малейшее расхождение - и очистка не сработает.
Директивы allow 127.0.0.1; deny all; ограничивают доступ к эндпоинту очистки только с локальной машины. Это обязательная мера безопасности: открытый purge-эндпоинт позволит любому удалить кэш вашего сайта.
Для очистки конкретной страницы выполните запрос с сервера:
curl -X GET http://127.0.0.1/purge/shop/product-123/
Более детально точечная инвалидация по URL и регулярным выражениям разобрана в статье о точечной очистке кэша Nginx.
Массовая очистка кэша FastCGI без простоя
Полная очистка кэша через find /var/cache/nginx -type f -delete работает, но создаёт резкий всплеск нагрузки: все страницы начинают генерироваться одновременно. На высоконагруженном проекте это может привести к деградации сервиса или отказу PHP-FPM. Массовую очистку нужно выполнять постепенно.
Скрипт для постепенной очистки кэша
Скрипт ниже удаляет файлы кэша пакетами по 100 штук с паузой 0.5 секунды между пакетами. Это растягивает нагрузку во времени и позволяет PHP-FPM обрабатывать запросы без перегрузки:
#!/bin/bash
CACHE_DIR="/var/cache/nginx/fastcgi"
BATCH_SIZE=100
PAUSE=0.5
find "$CACHE_DIR" -type f -print0 | while IFS= read -r -d '' file; do
rm -f "$file"
count=$((count + 1))
if [ $((count % BATCH_SIZE)) -eq 0 ]; then
sleep "$PAUSE"
fi
done
echo "Очистка завершена: удалено $count файлов"
Параметры BATCH_SIZE и PAUSE подбирайте под мощность сервера. Для слабых VPS уменьшите размер пакета до 50 и увеличьте паузу до 1 секунды. Для мощных выделенных серверов можно увеличить пакет до 500 файлов. Тестируйте на staging-окружении перед запуском в production.
Альтернативный подход - очистка по возрасту файлов. Удалите только кэш старше определённого времени, оставив свежие записи:
find /var/cache/nginx/fastcgi -type f -mmin +60 -delete
Эта команда удаляет файлы, не изменявшиеся более 60 минут. Свежий кэш остаётся нетронутым, что снижает нагрузку при повторной генерации.
Готовые скрипты для автоматической очистки через cron с логированием и интеграцией в системы мониторинга собраны в материале об автоматизации очистки кэша Nginx.
Очистка кэша для PHP-FPM и других CMS
Принцип очистки одинаков для всех FastCGI-приложений. Различается только ключ кэша и структура URL. Для чистого PHP-FPM без CMS конфигурация выглядит так:
fastcgi_cache_path /var/cache/nginx/php levels=1:2 keys_zone=PHP:50m inactive=30m;
server {
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_cache PHP;
fastcgi_cache_key "$host$request_uri";
fastcgi_cache_valid 200 15m;
}
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
fastcgi_cache_purge PHP "$host$1$is_args$args";
}
}
Для Drupal конфигурация аналогична WordPress, но нужно исключить из кэша административные страницы и запросы с куками авторизации:
set $no_cache 0;
if ($request_uri ~* "/(admin|user|cart|checkout)") {
set $no_cache 1;
}
if ($http_cookie ~* "SESS|wordpress_logged_in") {
set $no_cache 1;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_cache DRUPAL;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 30m;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
}
Ключевой момент: fastcgi_cache_key в location очистки должен быть идентичен ключу в location приложения. Если в приложении ключ включает $scheme$request_method, а в purge - только $host$request_uri, очистка не сработает. Проверяйте соответствие ключей в обеих секциях.
Типичные ошибки при очистке кэша и как их избежать
Первая ошибка - глобальное изменение конфигурации Nginx для решения локальной задачи. Патчинг основных директив без понимания их взаимодействия приводит к неработоспособности после обновлений. Вносите изменения точечно, тестируйте через nginx -t перед перезагрузкой.
Вторая ошибка - полная очистка кэша в часы пик. Всплеск нагрузки на PHP-FPM в момент максимального трафика может положить сервер. Планируйте массовую очистку на периоды низкой активности или используйте постепенные скрипты.
Третья ошибка - неверные права доступа к purge location. Если эндпоинт очистки доступен извне, злоумышленник может удалить весь кэш. Всегда закрывайте purge-эндпоинт директивами allow и deny, разрешая доступ только с localhost или доверенных IP.
Четвёртая ошибка - несовпадение ключа кэша. После изменения fastcgi_cache_key старый кэш становится недостижимым для очистки через purge. Перед изменением ключа очистите существующий кэш или учтите, что старые файлы останутся на диске до истечения inactive.
Диагностику ошибок Permission denied, устаревшего контента и проблем 404/502 после очистки разбираем в статье о типичных ошибках очистки кэша Nginx.
Заключение: выбор метода очистки под вашу задачу
Для точечной инвалидации отдельных страниц используйте ngx_cache_purge с эндпоинтом /purge. Это точный и безопасный метод, который не затрагивает остальной кэш. Для полной очистки применяйте скрипты с пакетным удалением и паузами, чтобы избежать пиковой нагрузки на PHP-FPM. Перед внесением изменений в production проверяйте конфигурацию командой nginx -t и тестируйте сценарии на staging-окружении. Правильно настроенная очистка кэша поддерживает актуальность контента без ущерба для производительности сервера.