Типова сцена: 1000 RPS і бекенд захлинається
Навантажене застосування (1000 RPS) легко впирається в ліміти бази даних або утилізацію CPU через повторювані обчислення. Бекенд на Node.js або Python важко обробляє кожен запит, особливо якщо є повторювані SQL-запити або важкі шаблони. Час відповіді може сягати 500ms, а P99 — зашкалювати. Правильно налаштований reverse proxy з кешуванням вирішує кілька завдань: SSL termination, статична роздача, кешування відповідей та балансування. Ми часто бачимо проекти, де бекенд віддає кожен запит напряму, а nginx стоїть лише як SSL-термінатор — це прямий шлях до перевантаження.
Наші інженери за 10+ років налаштували сотні таких схем. Результат: час відповіді падає на 70% для кешованих запитів, навантаження на бекенд знижується в рази. Порівняння: кеш nginx роздається в 10 разів швидше, ніж кеш Redis/Memcached на бекенді (мікросекунди проти мілісекунд). Вартість такого рішення — від кількох годин роботи, а економія ресурсів сервера може сягати тисяч доларів на місяць. Наприклад, після впровадження кеша можна скоротити кількість серверів з 5 до 2, заощаджуючи $3000 щомісячно.
Базова конфігурація reverse proxy
upstream backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.fullchain.pem;
ssl_certificate_key /etc/ssl/private/example.com.key;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
}keepalive 32 та proxy_http_version 1.1 з Connection "" — обов'язкова пара для persistent connections. Без неї кожен запит відкриває нове TCP-з'єднання, що на навантаженому сервері виливається в тисячі TIME_WAIT. TLS handshake займає близько 2ms, а віддача з кешу — менше 0.1ms, тому persistent connections критичні.
Кешування відповідей бекенду
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=backend_cache:10m max_size=100m inactive=60m use_temp_path=off;
server {
location /api/ {
proxy_cache backend_cache;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}
}proxy_cache_use_stale — один із найважливіших параметрів. При помилці бекенду nginx віддає застарілий кеш замість 502. updating захищає від Thundering Herd: поки один запит оновлює кеш, інші отримують старе значення. Згідно з офіційною документацією nginx (https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_use_stale), це ключовий засіб для високонавантажених систем. Додайте заголовок X-Cache-Status — побачите HIT, MISS, STALE або EXPIRED.
Як перевірити роботу кешу?
Додайте заголовок add_header X-Cache-Status $upstream_cache_status; і дивіться у відповіді HIT, MISS, STALE тощо. Також спостерігайте за падінням часу відповіді та навантаження на бекенд. P99 latency має знизитися з 500ms до 50ms. Для моніторингу використовуйте Prometheus метрики з nginx stub_status.
Які заголовки впливають на кешування?
Бекенд керує кешем через HTTP-заголовки. Якщо бекенд повернув Cache-Control: no-cache, nginx не кешує відповідь. Для примусової інвалідації використовуйте purge API:
location ~ /purge(/.*) { allow 127.0.0.1; deny all; proxy_cache_purge backend_cache "$scheme$host$1"; } Використовуйте curl: curl -X PURGE http://localhost/purge/api/products/123.
Кешування статики та роздача напряму
Статичні файли (jpg, css, js тощо) можна кешувати або віддавати напряму з nginx, минаючи бекенд. Пряма віддача знижує навантаження на CPU бекенду на 30–50%. Приклад для статики з хешем:
location /static/ {
alias /var/www/app/public/static/;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
gzip_static on;
}immutable говорить браузеру: файл ніколи не зміниться, не роби умовний запит.
Чому варто використовувати nginx для кешування, а не кеш на бекенді?
| Критерій | Кеш на nginx | Кеш на бекенді (Redis/Memcached) |
|---|---|---|
| Час віддачі | Мікросекунди (з пам'яті ядра) | Мілісекунди (мережа + серіалізація) |
| Навантаження на бекенд | Відповідь не доходить до застосування | Застосування все одно обробляє запит |
| Холодний старт | Файловий кеш зберігається після перезапуску | Прогрів кешу після перезапуску |
| Складність налаштування | Конфіг nginx + purge API | Окремий сервер, клієнти, інвалідація |
Процес роботи
- Аудит: аналіз конфігурації, логів, метрик через
stub_statusабо Prometheus. Визначаємо вузькі місця: де кеш принесе найбільший ефект. - Проектування: вибір розміру кешу, зон, правил інвалідації. Розраховуємо keys_zone та max_size виходячи з середнього розміру відповіді (наприклад, 10M зона зберігає близько 80 000 ключів).
- Реалізація: розгортання reverse proxy з кешуванням, балансуванням, SSL. Використовуємо Ansible або Terraform для repeatable деплою.
- Тюнінг: підбір таймаутів, буферів, keepalive під характеристики бекенду. Наприклад, для бекенду з довгими відповідями збільшуємо proxy_read_timeout до 120s.
- Тестування: навантажувальне тестування за допомогою wrk або k6. Мета — P99 latency < 100ms для кешованих запитів.
| Масштаб | Термін |
|---|---|
| Базовий reverse proxy | 1 день |
| + кешування з purge API | 2–3 дні |
| + балансування кількох upstream | 3–5 днів |
Вартість розраховується індивідуально після аудиту інфраструктури та навантажувальних патернів. Зв'яжіться з нами — підготуємо пропозицію з урахуванням ваших завдань.
Що входить в роботу
- Повна документація конфігурації та інструкція з експлуатації.
- Доступ до репозиторію з Ansible-ролями або Terraform-модулями.
- Навчання команди (2 години): як скидати кеш, читати логи, тюнити параметри.
- Гарантія на налаштування — 30 днів.
Типова проблема: кешування аутентифікованих запитів
За замовчуванням nginx кешує відповіді без урахування заголовка Authorization. Один користувач може отримати відповідь, призначену іншому. Рішення: додати proxy_cache_bypass $http_authorization; або включити Authorization в cache key: proxy_cache_key "$scheme$host$request_uri$http_authorization";. Перевірте, що це не порушує безпеку.
Як правильно тюнити proxy_cache_use_stale?
proxy_cache_use_stale визначає, коли віддавати кеш при проблемах з бекендом. Значення updating — ключове для високонавантажених систем. Воно захищає від ефекту Thundering Herd: nginx дозволяє одному запиту оновити кеш, а інші отримують старе значення, не навантажуючи бекенд. Рекомендуємо завжди використовувати updating в комбінації з error timeout.
Замовте професійне налаштування — наші інженери з 10+ річним досвідом допоможуть розгорнути production-ready reverse proxy для вашого проекту. Отримайте консультацію вже сьогодні: ми проаналізуємо вашу інфраструктуру та запропонуємо оптимальну конфігурацію.







