# Кэширование в Nginx: proxy_cache и fastcgi_cache на практике

> Как настроить кэширование в Nginx через proxy_cache и fastcgi_cache: зона кэша, ключ, время жизни и сброс кэша для отдельных страниц.

## Зачем кэшировать ответы на уровне Nginx

Кэш на уровне Nginx хранит уже готовый ответ бэкенда и отдаёт его напрямую при повторном запросе, не трогая PHP-FPM или прокси-приложение. Для сайта с высокой посещаемостью это снимает основную нагрузку с CPU и базы данных: страница блога или карточка товара, которая не меняется каждую секунду, рендерится один раз, а дальше отдаётся из памяти или с диска.

Есть два типа кэша с одинаковой логикой, но разными источниками: `proxy_cache` кэширует ответы, полученные через `proxy_pass` (см. статью про [reverse proxy](https://www.zevshost.net/ru/kb/nginx-reverse-proxy/)), а `fastcgi_cache` — ответы от PHP-FPM, полученные через `fastcgi_pass`. Настройка обеих директив почти идентична.

## Настройка зоны кэша

Зона кэша объявляется один раз в блоке `http` и задаёт, где хранятся файлы и сколько памяти выделено под индекс ключей.

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

`keys_zone=proxy_cache:10m` — имя зоны и объём памяти под метаданные, примерно 8000 ключей на 1 МБ. `max_size=1g` ограничивает размер кэша на диске, `inactive=60m` удаляет файлы, к которым не обращались 60 минут, даже если они формально ещё не устарели.

## Использование proxy\_cache в location

Внутри server-блока зона подключается директивой `proxy_cache`, а время жизни ответа — директивой `proxy_cache_valid`.

```
location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_cache proxy_cache;
    proxy_cache_valid 200 10m;
    proxy_cache_valid 404 1m;
    add_header X-Cache-Status $upstream_cache_status;
}
```

Заголовок `X-Cache-Status` — самый быстрый способ отладки: значения HIT, MISS, EXPIRED и BYPASS сразу показывают, был ли ответ взят из кэша. Без этого заголовка догадаться о работе кэша можно только по времени ответа, что менее надёжно.

## fastcgi\_cache для сайтов на PHP

Для WordPress, Bitrix и других CMS на PHP-FPM кэш настраивается аналогично, только через `fastcgi_cache` и с ключом, который учитывает метод и куки.

```
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fcgi_cache:10m max_size=1g inactive=60m;

location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_cache fcgi_cache;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    fastcgi_cache_valid 200 10m;
    fastcgi_cache_bypass $cookie_PHPSESSID;
    fastcgi_no_cache $cookie_PHPSESSID;
}
```

Про сам путь настройки связки Nginx с PHP-FPM — в статье про [Nginx и PHP-FPM](https://www.zevshost.net/ru/kb/nginx-php-fpm-svyazka/). Кэшировать страницы для залогиненных пользователей обычно не нужно: `fastcgi_cache_bypass` и `fastcgi_no_cache` по кукам сессии исключают личный кабинет из общего кэша.

## Параметры кэша: что за что отвечает

| Директива | Назначение |
| --- | --- |
| proxy\_cache\_valid | время жизни ответа с конкретным кодом статуса |
| proxy\_cache\_key | формула ключа, по которому ищется запись в кэше |
| proxy\_cache\_bypass | условие, при котором кэш не читается |
| proxy\_no\_cache | условие, при котором ответ не сохраняется в кэш |
| proxy\_cache\_lock | один запрос идёт на бэкенд, остальные ждут его результат |

`proxy_cache_lock on;` важен на старте прогрева кэша: без него сотня одновременных запросов к ещё не закэшированной странице отправит сотню одинаковых запросов на бэкенд разом, что и называют cache stampede.

## Итог: чек-лист кэширования в Nginx

- Зона кэша создана директивой `proxy_cache_path` или `fastcgi_cache_path` в блоке http.
- Время жизни задано отдельно для успешных и для ошибочных ответов.
- Страницы с куками сессии и личным кабинетом исключены через `*_no_cache` и `*_bypass`.
- Заголовок `X-Cache-Status` добавлен для отладки и виден в ответе curl.
- Включён `proxy_cache_lock`, чтобы избежать одновременных запросов на холодный кэш.

---

Источник: https://www.zevshost.net/ru/kb/nginx-proxy-cache-keshirovanie/
