Настройка балансировки нагрузки через Nginx и HAProxy
Балансировщик нагрузки распределяет входящий трафик по нескольким бэкендам, исключает единую точку отказа и позволяет горизонтально масштабировать приложение без изменения клиентского кода.
Nginx как балансировщик
Nginx балансирует HTTP/HTTPS и TCP из коробки. Подходит для большинства веб-приложений: проксирует запросы к бэкендам, проверяет их здоровье, кэширует ответы.
# /etc/nginx/conf.d/myapp.conf
upstream myapp_backend {
# Round-robin по умолчанию
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
# Keepalive соединения к бэкендам
keepalive 32;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://myapp_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_send_timeout 60s;
proxy_read_timeout 60s;
proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 2;
}
}
Алгоритмы балансировки Nginx
# Least Connections — меньше активных соединений = больше запросов
upstream backend_lc {
least_conn;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
# IP Hash — сессионная привязка по IP клиента
upstream backend_sticky {
ip_hash;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
# Weighted Round-Robin — сервер с весом 3 получает втрое больше запросов
upstream backend_weighted {
server 10.0.1.10:8080 weight=3; # мощнее
server 10.0.1.11:8080 weight=1; # слабее
}
# Резервный сервер (используется только если основные недоступны)
upstream backend_backup {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.20:8080 backup;
}
Nginx health checks (Nginx Plus / open-source)
В open-source Nginx пассивная проверка здоровья: сервер исключается после N ошибок за временной интервал.
upstream backend {
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 max_fails=3 fail_timeout=30s;
}
Активные health checks доступны в Nginx Plus или через модуль nginx_upstream_check_module:
upstream backend {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "GET /health HTTP/1.0\r\nHost: example.com\r\n\r\n";
check_http_expect_alive http_2xx;
}
HAProxy для высоких нагрузок
HAProxy — специализированный балансировщик. Обрабатывает миллионы одновременных соединений, поддерживает L4 (TCP) и L7 (HTTP), имеет встроенную статистику и ACL.
# /etc/haproxy/haproxy.cfg
global
log /dev/log local0
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
maxconn 100000
nbthread 4
cpu-map auto:1/1-4 0-3
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
timeout connect 5s
timeout client 30s
timeout server 60s
timeout http-request 10s
errorfile 503 /etc/haproxy/errors/503.http
# Фронтенд: приём соединений
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1
# HTTPS redirect
http-request redirect scheme https unless { ssl_fc }
# ACL: маршрутизация по пути
acl is_api path_beg /api/
acl is_admin path_beg /admin/
use_backend api_backend if is_api
use_backend admin_backend if is_admin
default_backend web_backend
# Бэкенд веб-приложения
backend web_backend
balance leastconn
option httpchk GET /health HTTP/1.1\r\nHost:\ example.com
http-check expect status 200
cookie SERVERID insert indirect nocache
server web01 10.0.1.10:8080 check inter 3s rise 2 fall 3 cookie web01
server web02 10.0.1.11:8080 check inter 3s rise 2 fall 3 cookie web02
server web03 10.0.1.12:8080 check inter 3s rise 2 fall 3 cookie web03
# API бэкенд
backend api_backend
balance roundrobin
option httpchk GET /api/health
http-check expect status 200
server api01 10.0.2.10:3000 check inter 2s
server api02 10.0.2.11:3000 check inter 2s
# Admin с ограничением по IP
backend admin_backend
acl admin_network src 10.0.0.0/8
http-request deny unless admin_network
server admin01 10.0.3.10:8080 check
# Статистика HAProxy
frontend stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:strongpassword
stats show-legends
stats show-node
SSL Termination в HAProxy
# Объединить fullchain и privkey в один PEM-файл
cat /etc/letsencrypt/live/example.com/fullchain.pem \
/etc/letsencrypt/live/example.com/privkey.pem \
> /etc/haproxy/certs/example.com.pem
chmod 600 /etc/haproxy/certs/example.com.pem
HAProxy TCP балансировка
Для баз данных, Redis, WebSocket:
frontend mysql_front
bind *:3306
mode tcp
default_backend mysql_backend
backend mysql_backend
mode tcp
balance roundrobin
option mysql-check user haproxy_check
server db01 10.0.4.10:3306 check
server db02 10.0.4.11:3306 check backup
Keepalived для High Availability балансировщика
Два балансировщика (primary + backup) с виртуальным IP — при падении primary, backup перехватывает VIP за секунды.
# /etc/keepalived/keepalived.conf (primary)
vrrp_script check_haproxy {
script "pidof haproxy"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass secretpassword
}
virtual_ipaddress {
10.0.0.100/24 # VIP
}
track_script {
check_haproxy
}
}
# /etc/keepalived/keepalived.conf (backup)
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
# остальное то же самое
}
Сравнение Nginx и HAProxy
| Характеристика | Nginx | HAProxy |
|---|---|---|
| Алгоритмы балансировки | round-robin, least-conn, ip-hash, random | round-robin, least-conn, source, uri, hdr, rdp-cookie |
| Активные health checks | Только Nginx Plus | Встроено |
| Sticky sessions | ip_hash | Cookie-based, гибко |
| L4 TCP балансировка | stream module | Нативно |
| Статистика | Базовая | Детальная встроенная |
| Статический контент | Отлично | Не предназначен |
| RAM на соединение | ~2 KB | ~10 KB |
| ACL/маршрутизация | Простые | Очень гибкие |
Nginx предпочтительнее когда нужен и веб-сервер, и балансировщик в одном месте. HAProxy — для чистой балансировки на высоких нагрузках (50k+ RPS) с гибкими ACL.
Автоматическое обновление upstream
При динамической инфраструктуре (автоскейлинг) список бэкендов нужно обновлять без перезапуска.
# Скрипт обновления Nginx upstream через consul-template или собственную логику
import subprocess
import boto3
def update_nginx_upstream():
ec2 = boto3.client('ec2', region_name='eu-west-1')
response = ec2.describe_instances(Filters=[
{'Name': 'tag:Role', 'Values': ['app']},
{'Name': 'instance-state-name', 'Values': ['running']},
])
ips = [
i['PrivateIpAddress']
for r in response['Reservations']
for i in r['Instances']
]
config = "upstream myapp_backend {\n"
for ip in ips:
config += f" server {ip}:8080;\n"
config += " keepalive 32;\n}\n"
with open('/etc/nginx/conf.d/upstream.conf', 'w') as f:
f.write(config)
subprocess.run(['nginx', '-t'], check=True)
subprocess.run(['nginx', '-s', 'reload'], check=True)
Для HAProxy аналогично через Runtime API:
echo "add server web_backend/web04 10.0.1.13:8080" | \
socat /run/haproxy/admin.sock stdio
echo "set server web_backend/web04 state ready" | \
socat /run/haproxy/admin.sock stdio
Срок реализации
| Задача | Срок |
|---|---|
| Nginx балансировка + SSL termination | 1–2 дня |
| HAProxy + статистика + ACL | 2–3 дня |
| Keepalived HA-пара | +1 день |
| Динамическое обновление upstream | +1–2 дня |







