Настройка Nginx Reverse Proxy: кэширование, балансировка, SSL

Когда ваш бэкенд захлёбывается от повторяющихся запросов и время ответа растёт, мы настраиваем Nginx Reverse Proxy с кэшированием, балансировкой и SSL-терминацией. Наша команда реализует проект под ключ — от аудита конфигурации до внедрения и последующей поддержки, обеспечивая стабильную работу и снижение нагрузки на серверы.
Часто задаваемые вопросы

Типичная сцена: 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 Отдельный сервер, клиенты, инвалидация

Процесс работы

  1. Аудит: анализ конфигурации, логов, метрик через stub_status или Prometheus. Определяем узкие места: где кэш принесёт наибольший эффект.
  2. Проектирование: выбор размера кэша, зон, правил инвалидации. Рассчитываем keys_zone и max_size исходя из среднего размера ответа (например, 10M зона хранит около 80 000 ключей).
  3. Реализация: развёртывание reverse proxy с кэшированием, балансировкой, SSL. Используем Ansible или Terraform для repeatable деплоя.
  4. Тюнинг: подбор таймаутов, буферов, keepalive под характеристики бэкенда. Например, для бэкенда с долгими ответами увеличиваем proxy_read_timeout до 120s.
  5. Тестирование: нагрузочное тестирование с помощью 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 для вашего проекта. Получите консультацию уже сегодня: мы проанализируем вашу инфраструктуру и предложим оптимальную конфигурацию.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139