Практичні сценарії налаштування Nginx для L4/L7
Уявіть: ваш інтернет-магазин гальмує, половина запитів іде в таймаут, а моніторинг показує, що один сервер перевантажений на 90%, а два інших простоюють. Це класична проблема невірно налаштованого балансування. Типова картина: backend-сервери мають різну потужність (наприклад, один з 4 vCPU, два з 2 vCPU), і round-robin направляє рівну кількість запитів, перевантажуючи слабкі вузли. Це призводить до каскадного збільшення затримки — час відповіді TTFB злітає до 3-5 секунд, а частина запитів падає через обмеження з'єднань. Промислова L7 балансування на Nginx з використанням least_connections і ваг вирішує проблему.
На практиці ми стикалися з проектом, де через round-robin час відповіді сягав 10 секунд. Після переходу на least_conn з вагами навантаження вирівнялося, а час відповіді знизився на 40%. За нашими вимірами, least_connections працює в 2-3 рази ефективніше за round-robin при різній тривалості запитів. При середньому чеку 3000 гривень втрата кожного десятого клієнта обходиться в 900 000 гривень на рік.
У цій статті розповімо про реальні технічні складнощі, які зустрічаються на практиці — від втрати сесій до SSL passthrough — і як їх подолати.
Чому балансування L4/L7 критичне для високонавантажених проектів?
Відмова одного сервера може призвести до недоступності всього сервісу. Без коректних health checks і failover користувачі отримують помилки 502. Крім того, неоптимальний розподіл запитів збільшує час відгуку в 2-3 рази, що прямо впливає на конверсію. Балансування на рівні L4 (TCP/UDP) підходить для будь-яких протоколів, але не враховує вміст запиту. L7 (HTTP/HTTPS) дає гнучкість: можна маршрутизувати за URL, заголовками, cookies. Разом вони покривають будь-які сценарії.
Коли використовувати L4, а коли L7?
Вибір рівня залежить від задачі. L4 балансування (через модуль stream) незамінне для сервісів, де не потрібно аналізувати протокол: бази даних (MySQL, PostgreSQL), Redis, SSH. Воно вносить мінімальну затримку (близько 1 мс). L7 підходить для HTTP-застосунків, де потрібні sticky sessions, канарковий деплой або A/B тестування. Наприклад, для інтернет-магазину з кошиком — L7 з IP hash або cookie-based sticky. Для мікросервісної архітектури часто комбінують: L4 для балансування трафіку між подами, L7 для маршрутизації всередині.
Проблеми, які ми вирішуємо
- Нерівномірний розподіл навантаження. Round-robin не завжди рівномірний: при нерівномірному навантаженні на запити (наприклад, одні запити важчі за інші) сервери забиваються нерівномірно. Ми використовуємо least_connections або weighted least_connections, щоб це компенсувати.
- Втрата сесій при збої backend. Без sticky sessions користувач знову потрапляє на інший сервер, втрачаючи дані кошика. Ми впроваджуємо cookie-based sticky або
hash $cookie_SERVERID consistent. - Некоректні health checks. Якщо пасивна перевірка не спрацьовує, трафік іде на сервер, що впав. Налаштовуємо
max_failsіfail_timeout, а для критичних систем — активні health checks через Nginx Plus або зовнішній моніторинг. - SSL passthrough для L4. Проксування HTTPS без розшифровки вимагає ssl_preread + SNI маршрутизацію. Це неочевидне налаштування, яке часто упускають.
Як ми це робимо: стек і конфігурація
Використовуємо Nginx Open Source (стабільна версія) або Nginx Plus при необхідності enterprise-функцій. У проектах застосовуємо GitOps-підхід: конфіги зберігаються в Git, деплой через Ansible або Terraform. Нижче — приклад робочої конфігурації для типового проекту інтернет-магазину.
L7 HTTP балансування
# /etc/nginx/conf.d/upstream.conf
upstream app_rr {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
keepalive 64;
}
upstream app_lc {
least_conn;
server 10.0.1.10:8080;
server 10.0.1.11:8080 weight=2;
server 10.0.1.12:8080;
}
upstream app_ip_hash {
ip_hash;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080 down;
}
upstream app_random {
random two least_conn;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}Порівняння алгоритмів балансування
| Алгоритм | Sticky | Ваги | Рівномірність | Використання |
|---|---|---|---|---|
| Round-robin | Ні | Так | Хороша при однакових запитах | Загальний випадок |
| Least_connections | Ні | Так | Відмінна при різній тривалості запитів | API, WebSockets |
| IP hash | Так | Ні | Середня за NAT | Stateful застосунки |
| Random two least_conn | Ні | Так | Краща при >2 серверів | Мікросервіси |
Таблиця порівняння L4 та L7 балансування
| Характеристика | L4 (stream) | L7 (HTTP) |
|---|---|---|
| Рівень | TCP/UDP | HTTP/HTTPS |
| Аналіз запиту | Ні (тільки порт/IP) | URL, заголовки, cookies |
| Sticky sessions | Ні (тільки IP hash) | Cookie-based, IP hash |
| Продуктивність | Висока (мінімальна затримка) | Нижча за рахунок розбору протоколу |
| Підтримувані сервіси | Будь-які TCP (MySQL, Redis, SSH) | HTTP-застосунки, API |
| Приклад налаштування | stream { upstream { server ... } } |
upstream { server ... } location / { proxy_pass ... } |
Health checks і failover
upstream app_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 backup;
keepalive 64;
keepalive_requests 1000;
keepalive_time 1h;
}
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
location / {
proxy_pass http://app_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_next_upstream error timeout http_500 http_502 http_503;
proxy_next_upstream_tries 2;
proxy_next_upstream_timeout 10s;
}
}proxy_next_upstream — потужний, але небезпечний інструмент. Ми вмикаємо http_500 тільки після ретельного аналізу: якщо запит був POST і вже виконався частково, повторна відправка може дублювати операцію. Тому для ідемпотентних методів (GET, PUT) — так, для POST — з обережністю.
Cookie-based Sticky Sessions
upstream app_sticky {
hash $cookie_SERVERID consistent;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
} L4 TCP балансування через stream модуль
stream {
log_format basic '$remote_addr [$time_local] ' '$protocol $status $bytes_sent $bytes_received ' '$session_time';
access_log /var/log/nginx/stream-access.log basic;
upstream mysql_cluster {
least_conn;
server 10.0.1.20:3306;
server 10.0.1.21:3306;
server 10.0.1.22:3306 backup;
}
server {
listen 3306;
proxy_pass mysql_cluster;
proxy_connect_timeout 5s;
proxy_timeout 300s;
}
upstream https_backends {
server 10.0.1.10:443;
server 10.0.1.11:443;
}
server {
listen 443;
proxy_pass https_backends;
ssl_preread on;
}
}Для моніторингу upstream використовуємо stub_status + Prometheus-експортер — це дає метрики nginx_up, nginx_connections_active тощо.
Розширена конфігурація з резервуванням
upstream app_cluster {
least_conn;
server 10.0.1.10:8080 max_fails=5 fail_timeout=60s;
server 10.0.1.11:8080 max_fails=5 fail_timeout=60s;
server 10.0.1.12:8080 backup;
keepalive 128;
}
server {
listen 80 default_server;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
location / {
proxy_pass http://app_cluster;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
} Процес роботи
- Аналітика — збираємо архітектуру, метрики поточного навантаження, визначаємо алгоритм і кількість upstream-серверів.
- Проектування — проектуємо конфігурацію, узгоджуємо health checks, timeout-и, політики retry.
- Реалізація — налаштовуємо Nginx, розгортаємо через GitOps (Ansible/Terraform), перевіряємо на staging.
- Тестування — навантажувальне тестування, перевірка failover, моніторинг.
- Деплой — blue-green або canary rollout з нульовим downtime.
Строки та вартість
Стандартний проект (до 5 upstream-серверів) займає від 1 до 3 днів. Вартість розраховується індивідуально — залежить від складності конфігурації, необхідності sticky sessions та інтеграції з моніторингом. Замовте налаштування балансування у професіоналів — залиште заявку на сайті.
Що входить у роботу
- Налаштування Nginx L4/L7 балансування з обраним алгоритмом.
- Health checks і failover.
- Cookie-based sticky sessions (при необхідності).
- Моніторинг (stub_status + Prometheus, або налаштування Datadog).
- Документація конфігурації та процедури експлуатації.
- Навчання вашої команди основам підтримки.
- 2 тижні післяпускової підтримки.
Гарантія та досвід
Наші інженери мають сертифікати NGINX і Kubernetes, а за плечима — понад 50 реалізованих проектів з балансування. Налаштування закріплюється SLO з гарантією відмовостійкості.
Отримайте консультацію експерта — зв'яжіться з нами, щоб обговорити вашу архітектуру. Ми допоможемо вибрати правильний алгоритм і налаштувати моніторинг.
Джерело: Балансування навантаження







