NGINX: балансировка нагрузки и обратное проксирование

Быстрые ссылки
How NGINX Load Balancing Works
Proxying to the Backend
NGINX обычно служит веб‑сервером, но также отлично работает как обратный прокси и балансировщик нагрузки — сетевой элемент, который принимает запросы и распределяет их по нескольким серверам приложений.
Как работает балансировка нагрузки NGINX
Основная идея балансировщика нагрузки — он располагается между пользователем и набором серверов и проксирует запросы этим серверам. Чаще всего используется как минимум два сервера, чтобы трафик можно было равномерно распределять.

Большая часть конфигурации связана с тем, как NGINX выбирает сервер из upstream. По умолчанию применяется round‑robin: запросы отправляются по очереди, обеспечивая равномерную нагрузку.
Однако часто требуется сохранение сессии (session persistence), когда один пользователь должен в течение сессии попасть на тот же сервер. Пример: корзина покупок хранится локально на одном приложении — при переключении сервера в середине сессии приложение может вести себя некорректно. Многие такие проблемы решаются централизованным хранилищем (Redis, базы данных), но сохранение сессии остаётся распространённым требованием.
В NGINX набор серверов называется upstream и задаётся списком адресов. Пример базового upstream с указанием веса:
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com;
}Здесь мы указали weight, чтобы отдавать больше трафика более мощному серверу. У upstream есть и другие опции: max_conns, различные таймауты. В NGINX Plus можно настроить health checks, чтобы не направлять трафик на серверы с проблемами.
Сохранение сессий (session persistence)
Самая простая форма сохранения сессии — ip_hash. NGINX использует IP клиента, чтобы привязать его к конкретному серверу:
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}ip_hash обязателен для сокетных приложений и всего, что требует устойчивого соединения к одному бэкенду. Если вы не хотите опираться на IP, можно кастомизировать хеш:
upstream backend {
hash $scheme$request_uri consistent;
server backend1.example.com;
server backend2.example.com;
}Опция “consistent” помогает при динамическом изменении списка серверов (меньше перераспределения ключей).
Другие алгоритмы распределения
Если сохранение сессии не нужно, можно использовать более умные алгоритмы, чем базовый round‑robin:
- least_conn — выбирает сервер с наименьшим числом активных соединений:
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}- least_time — выбирает сервер, который отвечает быстрее (по заголовку или по последнему байту):
upstream backend {
least_time header;
server backend1.example.com;
server backend2.example.com;
}NGINX Plus предлагает дополнительные возможности для сохранения сессий и распределения нагрузки, но для большинства случаев IP‑хеш и least_conn вполне достаточны.
Важно: выбор алгоритма зависит от характера нагрузки и от того, где хранится состояние приложения. Если состояние централизовано, можно смело использовать least_conn или least_time.
Проксирование запросов к backend
После настройки upstream внутри location блоков используйте proxy_pass, чтобы перенаправлять запросы на backend.
Пример для HTTP:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Для HTTPS нужно использовать proxy_pass с https и настроить SSL на входящем сервере (и при необходимости SSL между NGINX и бэкендом):
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/certs/server.key;
ssl_client_certificate /etc/ssl/certs/ca.crt;
location / {
proxy_pass https://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Классические заголовки X-Forwarded-For и X-Real-IP помогают приложению видеть реальный IP клиента.
Практические советы и безопасность
- Всегда настраивайте таймауты proxy_connect_timeout, proxy_send_timeout и proxy_read_timeout. Без них зависшие соединения могут съедать воркеры.
- Ограничивайте max_conns и weight для балансировки в кластере с неоднородными ресурсами.
- Включайте health checks (NGINX Plus или сторонние инструменты) для автоматического исключения упавших бэкендов.
- Для публичных сервисов используйте HTTPS и проверку сертификатов при соединении с бэкендом.
Примечание: при использовании ip_hash учитывайте NAT и прокси: несколько пользователей за одним NAT будут казаться одним IP.
Когда такой подход не подойдёт
- Реальные sticky‑сессии на основе cookie: если нужно привязать сессию к пользователю независимо от IP, лучше использовать cookie‑based sticky или централизованное хранилище сессий.
- Горизонтальное масштабирование stateful‑сервисов лучше решать на уровне приложения (разделяемое хранилище, кэширование) вместо полагания только на балансировщик.
- Если вам нужны продвинутые health checks, мониторинг и динамическое управление пулом — рассмотрите NGINX Plus, облачные балансировщики или HAProxy.
Альтернативные подходы
- DNS‑round robin — прост, но нет контроля состояния серверов.
- Аппаратные/облачные балансировщики (AWS ELB/ALB, GCP Load Balancer) — управляемые сервисы с интегрированным мониторингом и авто‑масштабированием.
- HAProxy — гибкий со множеством алгоритмов и метрик, хорош альтернатива для высоконагруженных систем.
Чек‑лист по ролям
DevOps:
- настроить upstream и health checks;
- задать таймауты и ограничения max_conns/weight;
- настроить логирование и метрики (status, Prometheus экспортер);
- протестировать сценарии отказа и восстановления.
Разработчик приложения:
- обеспечить идемпотентность и корректную обработку заголовков X‑Forwarded‑For/Host;
- использовать централизованное хранилище сессий при необходимости.
Специалист по безопасности:
- включить TLS между пользователем и NGINX;
- при необходимости включить TLS между NGINX и backend;
- следить за уязвимостями и применять политики CORS, CSP.
Мини‑методология развёртывания
- Подготовка: описать требуемое поведение сессий и SLA.
- Настройка upstream: выбрать алгоритм (ip_hash/least_conn/least_time).
- Настройка таймаутов и лимитов.
- Включение логирования и health checks.
- Тестирование: симулировать отказ бэкенда, проверять корректное перераспределение.
- Наблюдение: мониторинг метрик, корректировка весов и таймаутов.
Критерии приёмки
- Запросы равномерно распределяются в соответствии с выбранным алгоритмом.
- В случае деградации одного бэкенда трафик перестаёт идти к нему (health checks) или система быстро восстанавливается.
- Сохранение сессии (если требуется) работает корректно для типичных пользователей.
- Логи и метрики собираются и доступны для анализа.
Шпаргалка конфигураций (коротко)
- Round‑robin (по умолчанию): просто перечислить server в upstream.
- Sticky по IP: ip_hash;
- Sticky по хешу: hash $scheme$request_uri consistent;
- Наименьшее число соединений: least_conn;
- Быстрый отклик: least_time header|last_byte;
Однострочный глоссарий
- upstream — пул бэкенд‑серверов, к которым NGINX проксирует запросы.
- ip_hash — алгоритм балансировки, привязывающий клиента к серверу по IP.
- proxy_pass — директива, отправляющая запросы на указанный backend.
Краткое резюме
NGINX — гибкий инструмент для балансировки нагрузки и проксирования. Выбор алгоритма зависит от характера приложения и требований к сессиям: ip_hash и cookie‑based sticky подходят при необходимости привязки пользователя к серверу; least_conn и least_time — для stateless приложений. Обязательно настраивайте таймауты, логирование и health checks, а также тестируйте поведение при отказах.
Важно: для масштабных и критичных систем рассмотрите использование управляемых балансировщиков или NGINX Plus для расширенных возможностей.
Похожие материалы
Herodotus — Android‑троян: признаки и защита
Включить новое меню Пуск в Windows 11
Панель полей сводной таблицы в Excel
Включить новое меню «Пуск» в Windows 11
Дубликаты Диспетчера задач в Windows 11 — исправление