Балансировщик принимает запросы и распределяет их по нескольким экземплярам сервиса. Он даёт масштабирование, отказоустойчивость (умерший экземпляр выводится) и единую точку для TLS, лимитов и логов.
L4 и L7
- L4 (транспортный уровень) видит IP и порты, балансирует TCP- и UDP-соединения, не разбирая содержимое. Быстро, подходит для любых протоколов: базы, gRPC без маршрутизации, MQTT. Примеры: LVS, HAProxy в режиме tcp, сетевые балансировщики облаков,
streamв nginx. - L7 (прикладной) понимает HTTP: маршрутизирует по хосту, пути, заголовкам, завершает TLS, добавляет заголовки, кеширует, ограничивает частоту. Примеры: nginx, HAProxy в режиме http, Envoy, Traefik, Application Load Balancer.
Алгоритмы
- Round robin (по умолчанию в nginx): по очереди, можно с весами
weight=3. - Least connections (
least_conn): туда, где меньше активных соединений. Хорош для запросов разной длительности. - Хеш (
ip_hash,hash $cookie_session consistent): один клиент на один бэкенд. Липкие сессии, кеши на бэкендах. Консистентное хеширование меньше перемешивает клиентов при добавлении узла. - Random two choices (
random two least_conn): выбрать двух случайных и взять менее загруженного, хорошо работает при нескольких балансировщиках.
nginx как reverse proxy
upstream api {
least_conn;
server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.12:8080 backup;
keepalive 32;
}
server {
listen 443 ssl;
server_name api.example.ru;
client_max_body_size 10m;
location /api/ {
proxy_pass http://api;
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 2s;
proxy_read_timeout 30s;
proxy_next_upstream error timeout http_502 http_503;
}
}
Что здесь важно:
keepaliveв upstream иproxy_http_version 1.1с пустымConnectionпереиспользуют соединения к бэкендам, иначе на каждый запрос открывается новое TCP-соединение.- Заголовки
X-Forwarded-*передают бэкенду реальный IP клиента и схему. Доверять им бэкенд должен только от своего балансировщика. proxy_passсо слешем в конце (http://api/) заменяет совпавшую часть location, без слеша передаёт URI как есть. Частый источник 404 после настройки.- По умолчанию
client_max_body_size 1m: загрузка большого файла получит 413.
Health checks
Открытый nginx делает пассивные проверки: если за время fail_timeout набралось max_fails неудачных попыток обращения к серверу, он считается недоступным на тот же fail_timeout (по умолчанию max_fails=1, fail_timeout=10s). Что считается неудачей, задаёт proxy_next_upstream. Активные проверки (периодический запрос на /health) есть в NGINX Plus, HAProxy, Envoy и облачных балансировщиках. В Kubernetes роль активных проверок выполняет readiness probe.
Повторы запросов
proxy_next_upstream пересылает запрос на другой сервер при ошибке. Неидемпотентные запросы (POST, PATCH) по умолчанию не повторяются, если запрос уже ушёл на бэкенд: иначе можно дважды списать деньги. Не включайте non_idempotent бездумно.
Таймауты и коды ошибок
- 502 Bad Gateway: бэкенд отказал в соединении, оборвал его или вернул мусор. Часто: приложение упало или не слушает порт.
- 504 Gateway Timeout: бэкенд не ответил за
proxy_read_timeout(или не принял соединение заproxy_connect_timeout). - 499: код nginx, клиент закрыл соединение, не дождавшись ответа. Рост 499 часто означает медленный бэкенд.
- 503: нет доступных серверов в upstream или сработал лимит запросов.
Лимиты
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
location /login { limit_req zone=perip burst=20 nodelay; }
rate средняя скорость, burst размер очереди всплеска, nodelay обслуживает всплеск сразу. Отклонённые запросы получают 503 (меняется limit_req_status 429).
Логи
Формат combined: IP, время, строка запроса, статус, размер, referer, user agent. В свой формат полезно добавить $request_time (полное время запроса) и $upstream_response_time (время ответа бэкенда). Разница между ними показывает, где теряется время: в бэкенде или в медленном клиенте и сети. Логи по умолчанию ротирует logrotate, после ротации nginx получает сигнал USR1 и переоткрывает файлы.
Изменение конфига без простоя
nginx -t проверяет конфиг, nginx -s reload (или systemctl reload nginx) запускает новые воркеры с новым конфигом, старые дорабатывают текущие запросы. Перезапуск restart рвёт соединения.
Частые ошибки
- Нет
keepaliveк upstream: тысячи соединений в TIME_WAIT. proxy_read_timeout60 секунд по умолчанию для API, который должен отвечать за секунду.- Доверие
X-Forwarded-Forот кого угодно: клиент подделает свой IP. restartвместоreload.
Что спросят на собесе
- Чем L4 отличается от L7 балансировки.
- Какие алгоритмы балансировки знаете и когда какой.
- Чем 502 отличается от 504 и как искать причину.
- Как nginx понимает, что бэкенд умер.
- Как получить реальный IP клиента за балансировщиком.