Кэширование ответов: proxy_cache и микрокэш

Рейтинг: 67.6% · 8 голосов
Самый подробный курс по Nginx - от первого конфига до production API-gateway. Архитектура и event loop, контексты и location, виртуальные хосты, статика, reverse proxy и upstream-балансировка, кэширование, HTTPS и TLS (post-quantum), HTTP/2 и HTTP/3 QUIC, безопасность и rate limiting, realip, JSON-логи и сквозная трассировка, метрики, тюнинг и траблшутинг. Плюс OpenResty (Lua, фазы, JWT, динамика) и Angie (нативные Prometheus, ACME, dynamic upstream). На основе эталонного gateway и лучших практик. Для новичков и SRE/DevOps. Актуально на 2026 (nginx 1.30/1.31, Angie, ingress-nginx EOL -> Gateway API).
Ответить
Аватара пользователя
Igor_NgINX
Сообщения: 44
Зарегистрирован: 11 май 2026, 05:31

Кэширование ответов: proxy_cache и микрокэш

Сообщение Igor_NgINX »

Оглавление курса (44)
  1. Что такое Nginx и почему он захватил веб
  2. Установка Nginx, Angie и OpenResty: пакеты, версии, Docker
  3. Первый конфиг с нуля: минимальный сервер за 5 минут
  4. Архитектура процессов: master, worker и event loop
  5. Анатомия конфигурации: контексты, наследование и модульность
  6. Виртуальные хосты: server и server_name
  7. Директива location: матчинг и приоритеты по шагам
  8. Раздача статики: root, alias, try_files, sendfile
  9. Переменные, map и блок if
  10. rewrite, return и канонизация URL
  11. Работа с заголовками: add_header и proxy_set_header
  12. Модель доверия прокси-заголовков: realip и защита от спуфинга
  13. Сжатие: gzip, brotli и zstd
  14. Reverse proxy: proxy_pass и проброс запроса
  15. upstream и балансировка нагрузки
  16. Таймауты, повторы и устойчивость прокси
  17. FastCGI и PHP: nginx + PHP-FPM (и uwsgi/scgi)
  18. WebSocket, gRPC и стриминг через Nginx
  19. Кэширование ответов: proxy_cache и микрокэш (вы здесь)
  20. HTTPS и TLS: сертификаты, протоколы, шифры (2026)
  21. Let's Encrypt и ACME: certbot, acme.sh, нативный ACME Angie
  22. HTTP/2 и HTTP/3 (QUIC) в 2026
  23. Безопасность: заголовки, скрытие версии, ограничения
  24. Rate limiting и защита от перегрузки
  25. Контроль доступа: allow/deny, auth_basic, auth_request и mTLS
  26. Логирование: access_log, форматы и структурированный JSON
  27. Сквозная трассировка запросов и OpenTelemetry
  28. Метрики и мониторинг Nginx
  29. Производительность и тюнинг под нагрузку
  30. Траблшутинг: 502, 504, 403, 404 и debug-лог
  31. OpenResty: Nginx как платформа на LuaJIT
  32. Фазы обработки запроса и Lua-хуки
  33. Lua API: ngx.*, shared dict, cosocket и lua-resty-core
  34. Практика OpenResty: авторизация, JWT, кэш, Redis
  35. Angie: современный форк Nginx 2026
  36. Динамическая конфигурация и service discovery
  37. Nginx как API-gateway и Kubernetes Gateway API
  38. Динамические модули, njs и WAF
  39. Stream-модуль: проксирование TCP и UDP
  40. Деплой, перезагрузка и конфиг как код
  41. Сценарий: статика, SPA и кэширование за CDN
  42. Сценарий: микросервисный gateway по образцу ngx-trace-gateway
  43. Капстоун: собираем production-gateway с нуля
  44. Чек-лист безопасности, CVE 2026 и аудит конфигурации
Зачем вообще кэшировать на Nginx и какую боль это снимает

Представь типичную картину. У тебя бэкенд на PHP или Node, он на каждый запрос лезет в базу, рендерит шаблон, тратит 200-400 мс и кусок CPU. Пока запросов десяток в секунду - живёшь. А потом тебя постит крупный канал, и на главную одновременно валит 5000 человек. Бэкенд встаёт колом, база захлёбывается, ты смотришь в Grafana и видишь, как 504 заливают всю выдачу. При этом 90 процентов этих 5000 запросов абсолютно одинаковы: один и тот же URL, один и тот же ответ. Зачем рендерить его пять тысяч раз?

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

В этом уроке разберём nginx proxy_cache от и до: как объявляется зона через nginx proxy_cache_path, из чего собирается ключ, как читать X-Cache-Status, единый production-паттерн защиты бэкенда (lock + background_update + revalidate + use_stale), отдельно nginx микрокэш для динамики, второй слой через open_file_cache и - очень важно - где кэш стреляет тебе в ногу приватностью. Это не теория: всё, что покажу, лежит в global_cache.conf и global_proxy.conf эталонного gateway, на нём и разберём.

Изображение

proxy_cache_path: где и как Nginx хранит nginx кэш

Кэш начинается с зоны. Объявляется она в контексте http, один раз на весь сервер:

Код: Выделить всё

proxy_cache_path /var/cache/nginx/gate levels=1:2 keys_zone=appcache:128m inactive=60m max_size=10g use_temp_path=off;
Разберём по косточкам, потому что каждый параметр тут несёт смысл.

/var/cache/nginx/gate - каталог на диске, куда лягут сами тела ответов. Каталог должен существовать и быть доступен пользователю, под которым крутится worker (обычно nginx или www-data), иначе при старте получишь ошибку прав.

levels=1:2 - схема вложенных подкаталогов. Имя файла кэша - это MD5 от ключа. levels=1:2 говорит: возьми последний символ хеша как имя каталога первого уровня, два предыдущих - второго. То есть файл с хешем ...c3d8a окажется в /var/cache/nginx/gate/a/d8/. Зачем? Если свалить миллион файлов в один каталог, многие файловые системы начинают тормозить на листинге и поиске inode. Раскладка по 256 на 256 подкаталогов держит в каждом каталоге сотни файлов вместо миллионов.

keys_zone=appcache:128m - вот это ключевой и часто недопонимаемый момент. Это зона в разделяемой памяти (shared memory) под имя appcache, и в ней лежат НЕ тела ответов, а только индекс: ключи, метаданные, флаги, таймеры. Сами тела - на диске. 128m памяти под индекс - это очень много: одна запись занимает примерно 0.5 КБ, значит 128m держат под рукой порядка 250 тысяч ключей одновременно. Имя appcache - это то, чем ты будешь ссылаться на зону в proxy_cache.

inactive=60m - если к объекту не обращались 60 минут, его выкинут из кэша, даже если по сроку жизни он ещё валиден. Это про вытеснение по неиспользуемости, не путать с TTL.

max_size=10g - потолок размера кэша на диске. При превышении специальный процесс cache manager начинает вычищать самые старые/невостребованные записи по LRU. Без max_size кэш будет расти, пока не забьёт диск.

use_temp_path=off - принципиально для I/O. По умолчанию Nginx сначала пишет тело во временный каталог (proxy_temp_path), а потом переносит в каталог кэша. Если temp и cache на разных файловых системах, перенос превращается в полное копирование. use_temp_path=off заставляет писать сразу в каталог кэша - убираем лишнее копирование. Ставь off почти всегда.

Зона объявлена, но ещё ничего не кэшируется. Чтобы location реально использовал кэш, нужна директива proxy_cache:

Код: Выделить всё

location /api/ {
    proxy_cache appcache;
    proxy_cache_valid 200 1h;
    proxy_pass http://backend_upstream;
}
proxy_cache appcache связывает location с зоной. proxy_cache_valid 200 1h - кэшировать ответы со статусом 200 на час. Можно перечислить несколько кодов: proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; - короткие 404 в кэше иногда спасают бэкенд от долбёжки по несуществующим путям, но осторожно с этим.

Ключ кэша: из чего складывается nginx proxy_cache_key и где приватная мина

Ключ - это то, по чему Nginx решает "это тот же самый ответ или другой". По умолчанию ключ равен "$scheme$proxy_host$request_uri". В эталонном gateway он расширен:

Код: Выделить всё

proxy_cache_key "$scheme$request_method$host$request_uri$http_authorization";
Логика тут есть: $request_method чтобы POST не выдавался из кэша как GET, $host чтобы домены не смешивались, $request_uri это путь плюс query string. А вот $http_authorization в конце - это намеренно поставленный учебный капкан, и сейчас объясню, почему он опасен.

Замысел был такой: "пусть у разных токенов будут разные записи кэша, чтобы Алисин ответ не утёк Бобу". Звучит логично, но это ловушка. Смотри, что происходит на деле. Алиса с токеном A дёргает /api/profile - Nginx кэширует её приватный профиль под ключом, куда входит токен A. Пока всё честно: Боб с токеном B получит свой ключ и свой запрос на бэкенд. Но проблема в другом - ты вообще закэшировал приватный персональный ответ на диске Nginx. Если Алиса дёрнет /api/profile дважды с одним токеном, второй раз ей отдаст Nginx из кэша, минуя любую проверку прав на бэкенде. Токен протух, доступ отозвали, юзера забанили - а Nginx всё ещё час отдаёт его старый профиль из appcache всем, кто придёт с тем же значением заголовка. Это дыра в авторизации и приватности.

Правильный подход - НЕ городить токен в ключ, а вообще не кэшировать то, что приватно. Для этого есть две директивы:

Код: Выделить всё

# Не сохранять ответ в кэш, если есть Authorization или сессионная кука
proxy_no_cache       $http_authorization $cookie_sessionid;
# Не отдавать из кэша (идти на бэкенд), при тех же условиях
proxy_cache_bypass   $http_authorization $cookie_sessionid;
Семантика: proxy_no_cache с непустым значением хоть одной переменной запрещает класть ответ в кэш. proxy_cache_bypass с непустым значением заставляет идти на бэкенд напрямую, игнорируя кэш на чтение (в X-Cache-Status увидишь BYPASS). Вместе они дают железное правило: есть Authorization или сессия - значит запрос персональный, кэш не трогаем ни на запись, ни на чтение. А кэшируем только анонимные публичные ответы. Это и безопасно, и эффективно: именно анонимный трафик обычно и есть твой пик под нагрузкой.

Запомни как мантру: кэш-ключ задаёт уникальность, а не приватность. Приватность решается через no_cache/bypass, а не запихиванием токена в ключ.

Единый паттерн устойчивости: lock, background_update, revalidate, use_stale

Теперь сердцевина урока - набор директив, который превращает наивный кэш в надёжный щит для бэкенда. В эталонном global_proxy.conf он собран в один блок, разберём по порядку.

proxy_cache_lock - защита от thundering herd (cache stampede). Представь: популярный объект протух (EXPIRED), и в эту секунду на него прилетело 1000 запросов. Без блокировки все 1000 обнаружат, что в кэше пусто/устарело, и ВСЕ разом ломанутся на бэкенд за свежей копией. Бэкенд, который ты кэшем как раз и защищал, получает залп в 1000 одинаковых тяжёлых запросов и падает. Это и есть стампед.

Код: Выделить всё

proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
С proxy_cache_lock on на бэкенд уходит только ОДИН запрос - лидер. Остальные ждут, пока лидер положит свежий ответ в кэш, и забирают его уже оттуда. proxy_cache_lock_timeout 5s - сколько максимум ждущий готов простоять в очереди; если лидер за 5 секунд не управился, ждущий тоже пойдёт на бэкенд (иначе при медленном лидере все встанут навечно).

proxy_cache_background_update - обновление в фоне.

Код: Выделить всё

proxy_cache_background_update on;
proxy_cache_revalidate on;
Когда запись протухла, по умолчанию клиент, который пришёл первым, ждёт, пока Nginx сходит на бэкенд и обновит её - то есть платит латентностью за чужое обновление. С background_update on Nginx отдаёт клиенту СТАРУЮ копию немедленно, а обновление запускает в фоновом подзапросе. В X-Cache-Status в этот момент ты увидишь UPDATING. Важная связка: background_update работает только если в proxy_cache_use_stale есть флаг updating (см. ниже) - без него фонового обновления не будет.

proxy_cache_revalidate - дешёвое обновление через условные запросы. Если бэкенд отдаёт ETag или Last-Modified, при обновлении протухшей записи Nginx пошлёт на бэкенд не обычный GET, а условный - с If-None-Match / If-Modified-Since. Если контент не менялся, бэкенд ответит 304 Not Modified без тела - Nginx просто продлит TTL существующей записи, не перекачивая мегабайты. Экономия трафика и времени на ровном месте.

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

Код: Выделить всё

proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
Смысл: если бэкенд отвалился (timeout, 502, 503) или вернул 500/429, а в кэше есть пусть и протухшая копия - отдай клиенту её, чем швырять в лицо 504. Флаг updating тут как раз и включает поведение "пока обновляемся - отдаём старое" (тот самый партнёр background_update). По сути это серверный аналог HTTP-расширений stale-while-revalidate (отдать старое, пока тихо обновляемся) и stale-if-error (отдать старое, если бэкенд лёг). Кстати, если бэкенд сам шлёт заголовок Cache-Control: stale-while-revalidate=30, современный Nginx это уважает и тебе не нужен флаг updating для этого объекта - он сам отдаст старое и обновит в фоне в пределах указанного окна.

Собранный воедино боевой блок (то, что и крутится в эталонном gateway):

Код: Выделить всё

location /api/ {
    proxy_cache appcache;
    proxy_cache_key "$scheme$request_method$host$request_uri";

    proxy_cache_valid 200 302 1h;
    proxy_cache_valid 404 1m;

    proxy_cache_lock on;
    proxy_cache_lock_timeout 5s;
    proxy_cache_background_update on;
    proxy_cache_revalidate on;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;

    proxy_no_cache     $http_authorization $cookie_sessionid;
    proxy_cache_bypass $http_authorization $cookie_sessionid;

    add_header X-Cache-Status $upstream_cache_status always;
    proxy_pass http://backend_upstream;
}
Обрати внимание: я убрал $http_authorization из ключа и перенёс его в no_cache/bypass. Так делать правильно.

X-Cache-Status: читаем, что происходит с nginx cache

Переменная $upstream_cache_status - твой главный диагностический инструмент. Выкидывай её в заголовок и в access-лог, без неё ты слепой. Значения:
  • MISS - в кэше не было, сходили на бэкенд, положили.
  • HIT - отдали из кэша, бэкенд не трогали. То, ради чего всё затевалось.
  • EXPIRED - запись была, но протухла по TTL; сходили на бэкенд за свежей.
  • UPDATING - запись протухла, отдаём старую, а свежую тянем в фоне (это background_update + use_stale updating в действии).
  • STALE - бэкенд недоступен/ошибся, отдали заведомо протухшую копию по proxy_cache_use_stale. Видишь STALE - значит бэкенду плохо, иди смотри.
  • BYPASS - кэш сознательно обойдён по proxy_cache_bypass (например, был Authorization).
Проверить руками просто - дёрни curl и посмотри заголовок:

Код: Выделить всё

$ curl -sI http://localhost/api/news | grep -i x-cache
X-Cache-Status: MISS

$ curl -sI http://localhost/api/news | grep -i x-cache
X-Cache-Status: HIT
Первый запрос - MISS (наполнили кэш), второй - HIT (отдали из памяти/диска). Если второй раз снова MISS - значит ответ не кэшируется, и надо разбираться: либо бэкенд шлёт Set-Cookie или Cache-Control: no-cache (Nginx по умолчанию это уважает), либо твой no_cache сработал. Здесь помогает proxy_ignore_headers, которым ты говоришь Nginx не обращать внимания на заголовки origin:

Код: Выделить всё

proxy_ignore_headers Expires Cache-Control Set-Cookie Vary;
С этим Nginx кэширует по СВОИМ правилам (proxy_cache_valid), а не по тому, что навыставлял бэкенд. Удобно, когда бэкенд не умеет в кэш-заголовки. Но это палка о двух концах: проигнорировав Set-Cookie, легко закэшировать персонализированный ответ - поэтому связка с proxy_no_cache по Authorization/сессии тут не роскошь, а обязательна.

Nginx микрокэш: кэшируем динамику на одну секунду

"Но у меня контент динамический, его нельзя кэшировать на час!" - частое возражение. И тут на сцену выходит nginx микрокэш (micro-caching). Трюк гениально простой: кэшируем динамический ответ всего на 1 секунду.

Считаем. Главная обновляется псевдо-реально, и под пиком на неё летит 1000 запросов в секунду. Без кэша - 1000 рендеров в секунду, бэкенд мёртв. С микрокэшем на 1 секунду - бэкенд рендерит страницу РОВНО ОДИН раз в секунду, остальные 999 запросов получают ту же копию из nginx cache. Свежесть данных - максимум секунда задержки, что для 99 процентов контента незаметно. А нагрузка на бэкенд падает в тысячу раз. Это самый дешёвый способ пережить хабраэффект.

Код: Выделить всё

location / {
    proxy_cache appcache;
    proxy_cache_valid 200 1s;          # вот он, микрокэш
    proxy_cache_lock on;               # без лока смысл теряется
    proxy_cache_use_stale updating error timeout;
    proxy_cache_background_update on;

    proxy_no_cache     $cookie_sessionid;
    proxy_cache_bypass $cookie_sessionid;

    add_header X-Cache-Status $upstream_cache_status always;
    proxy_pass http://backend_upstream;
}
Ключевой момент: микрокэш БЕЗ proxy_cache_lock почти бесполезен. На границе каждой секунды запись протухает, и без лока ты снова получаешь мини-стампед каждую секунду. Лок гарантирует, что обновляет запись один запрос, а с background_update остальные секунду живут на чуть устаревшей копии вместо ожидания. Микрокэш + lock + use_stale updating - это канонический рецепт "пережить нагрузку на динамике".

open_file_cache: второй слой кэша для статики

proxy_cache закрывает ответы бэкенда. А что со статикой, которую Nginx отдаёт сам с диска - css, js, картинки? Тут другой слой: open_file_cache. Он кэширует не содержимое файлов, а метаданные дескрипторов: результаты open(), stat(), существование файла, права, размер, mtime.

Зачем? Под нагрузкой на каждый запрос статики Nginx делает системные вызовы stat() и open(). Это дёшево поодиночке, но при 50k rps превращается в заметную нагрузку на ядро и диск. open_file_cache держит эти метаданные в памяти worker-а:

Код: Выделить всё

open_file_cache          max=2000 inactive=20s;
open_file_cache_valid    60s;
open_file_cache_min_uses 5;
open_file_cache_errors   on;
max=2000 - максимум описаний файлов в кэше. inactive=20s - выкинуть, если к файлу не обращались 20 секунд. open_file_cache_valid 60s - раз в минуту перепроверять, что метаданные ещё актуальны (файл не удалили/не подменили). open_file_cache_min_uses 5 - кэшировать только файлы, к которым обратились 5+ раз за inactive, чтобы не засорять кэш одноразовыми обращениями. open_file_cache_errors on - кэшировать и факт "файла нет": при долбёжке по несуществующему пути Nginx не будет каждый раз делать бесполезный системный вызов.

Важно понимать разницу: proxy_cache и open_file_cache - это два РАЗНЫХ кэша про разные вещи. Первый - про тела ответов бэкенда (динамика, проксирование). Второй - про дескрипторы файлов, которые Nginx отдаёт сам. На боевом шлюзе работают оба слоя одновременно.

Типичные грабли
  • Токен/кука в proxy_cache_key вместо no_cache. Разобрали выше - это утечка приватных ответов. Ключ - про уникальность, приватность - через proxy_no_cache/proxy_cache_bypass.
  • POST в кэше. По умолчанию Nginx кэширует только GET и HEAD (proxy_cache_methods). Не пытайся кэшировать POST - это почти всегда логическая ошибка.
  • Микрокэш без proxy_cache_lock. Каждую секунду на границе TTL - стампед. Лок обязателен.
  • background_update без use_stale updating. Без флага updating фоновое обновление не включится, и клиент будет ждать обновления синхронно. Эти две директивы ходят парой.
  • Кэширование ответов с Set-Cookie. Если proxy_ignore_headers Set-Cookie включён, а no_cache по сессии нет - закэшируешь чужую персонализацию. Классика утечки сессий.
  • use_temp_path не off на разных ФС. Temp и cache на разных файловых системах превращают каждую запись в полное копирование файла. Ставь use_temp_path=off.
  • Слишком короткий lock_timeout. Если лидер обновляет дольше lock_timeout, ждущие всё равно пойдут на бэкенд - стампед возвращается. Соизмеряй с реальным временем рендера.
Очистка кэша: proxy_cache_purge

Рано или поздно понадобится выбить конкретную запись из кэша - например, контент обновили вручную и ждать TTL нельзя. В open-source Nginx директива proxy_cache_purge живёт в стороннем модуле ngx_cache_purge (в Nginx Plus и в Angie есть встроенный механизм purge). Идея - выделить специальный метод/локацию, которая по ключу удаляет запись:

Код: Выделить всё

map $request_method $purge_method {
    PURGE   1;
    default 0;
}

location /api/ {
    proxy_cache appcache;
    proxy_cache_purge $purge_method;   # из модуля ngx_cache_purge
    proxy_pass http://backend_upstream;
}
Тогда запрос вида curl -X PURGE http://gateway/api/news вычистит запись по соответствующему ключу. Локацию PURGE обязательно закрой по IP (allow внутренние сети, deny all) - иначе любой желающий сможет сбрасывать тебе кэш и устраивать рукотворный стампед. Совсем грубый аналог без модуля - rm по каталогу кэша, но это не атомарно и индекс в shared memory придётся пересинхронизировать, так что для точечного purge лучше модуль, для тотального сброса - перезагрузка/очистка каталога.

Мини-лаба: собери кэш руками за 6 шагов

Понадобится Nginx (или OpenResty) и любой бэкенд, который умно отвечает - подойдёт даже python -m http.server или маленький echo-сервис на :9000.
  • Шаг 1. Создай каталог кэша: mkdir -p /var/cache/nginx/gate и дай права worker-у (chown).
  • Шаг 2. В http добавь зону: proxy_cache_path /var/cache/nginx/gate levels=1:2 keys_zone=appcache:128m inactive=60m max_size=10g use_temp_path=off;
  • Шаг 3. В location пропиши proxy_cache appcache; proxy_cache_valid 200 30s; proxy_pass на свой бэкенд; и add_header X-Cache-Status $upstream_cache_status always;
  • Шаг 4. nginx -t && nginx -s reload. Дёрни дважды: curl -sI localhost/ | grep -i x-cache. Первый MISS, второй HIT. Загляни в /var/cache/nginx/gate - там появились файлы в подкаталогах a/bc/.
  • Шаг 5. Добавь устойчивый блок: proxy_cache_lock on; proxy_cache_lock_timeout 5s; proxy_cache_background_update on; proxy_cache_revalidate on; proxy_cache_use_stale error timeout updating http_502 http_503; Останови бэкенд и снова сделай запрос - вместо 502 получишь STALE из кэша. Это и есть устойчивость.
  • Шаг 6. Поставь proxy_cache_valid 200 1s; и прогони нагрузку: while true; do curl -s -o /dev/null -w "%{http_code} " localhost/; done в одном терминале, а в логе бэкенда считай реальные хиты - увидишь примерно один запрос в секунду вместо шквала. Это микрокэш в работе.
Контрольные вопросы
  • Что хранится в зоне keys_zone (shared memory), а что - на диске в каталоге кэша? Почему 128m под индекс - это очень много записей?
  • Почему добавлять $http_authorization в proxy_cache_key - плохая идея, и через какие две директивы правильно исключать приватные ответы из кэша?
  • Зачем нужен proxy_cache_lock и что произойдёт с микрокэшем на 1 секунду, если лок выключить?
  • В каких случаях ты увидишь в X-Cache-Status значения UPDATING и STALE, и какие директивы за каждое из них отвечают?
Итог

nginx proxy_cache - это не "включил и забыл", а связка из ключа, TTL и набора директив устойчивости. Запомни главное: зона объявляется в nginx proxy_cache_path (индекс в памяти, тела на диске, use_temp_path=off); приватность решается через proxy_no_cache/proxy_cache_bypass, а НЕ токеном в ключе; production-щит бэкенда - это proxy_cache_lock + background_update + revalidate + use_stale в одном флаконе; nginx микрокэш на 1 секунду спасает динамику под пиком; open_file_cache - отдельный слой для статики; X-Cache-Status - твои глаза. Соберёшь эту комбинацию правильно - твой бэкенд переживёт нагрузку, которую без кэша не пережил бы никогда.
👍4 ❤️2 🔥1 😄 🤔
Аватара пользователя
redis1
Сообщения: 1
Зарегистрирован: 15 май 2026, 21:54

Re: Кэширование ответов: proxy_cache и микрокэш

Сообщение redis1 »

А я как раз словил это с микрокэшем без лока - под нагрузкой бэкенд каждую секунду ловил пачку одинаковых запросов на границе TTL. Добавил proxy_cache_lock on и use_stale updating, нагрузка упала в разы. Спасибо, теперь понятно почему именно так.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
michl26
Сообщения: 1
Зарегистрирован: 15 май 2026, 20:28

Re: Кэширование ответов: proxy_cache и микрокэш

Сообщение michl26 »

Вопрос про purge: если ngx_cache_purge нет в сборке, а на Angie встроенный механизм есть - то на ванильном опенрес можно как-то точечно бить запись без стороннего модуля, или только rm по каталогу и rg синхронизация индекса сама подтянется?
👍 ❤️2 🔥 😄 🤔1
Ответить
← Предыдущая глава
WebSocket, gRPC и стриминг через Nginx
Следующая глава →
HTTPS и TLS: сертификаты, протоколы, шифры (2026)

Все главы курса «Nginx профессионально: от первого конфига до API-gateway на OpenResty и Angie»

Поделиться темой: ✈ Telegram VK
Похожие запросы: Тюнинг и производительность nginxnginx и PHP-FPM: настройка FastCGIКэширование ответов в nginx (proxy_cache)Сжатие в nginx: gzip и brotli

Вернуться в «Nginx профессионально: от первого конфига до API-gateway на OpenResty и Angie»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя