Навіщо кешувати відповіді на рівні Nginx
Кеш на рівні Nginx зберігає вже готову відповідь бекенду і віддає її напряму при повторному запиті, не чіпаючи PHP-FPM чи проксі-застосунок. Для сайту з високою відвідуваністю це знімає основне навантаження з CPU і бази даних: сторінка блогу чи картка товару, яка не змінюється щосекунди, рендериться один раз, а далі віддається з пам'яті або з диска.
Є два типи кешу з однаковою логікою, але різними джерелами: proxy_cache кешує відповіді, отримані через proxy_pass (див. статтю про 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. Кешувати сторінки для залогінених користувачів зазвичай не потрібно: 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, щоб уникнути одночасних запитів на холодний кеш.