Балансировка нагрузки

Как трафик делится между серверами, чем L4 отличается от L7 и почему sticky sessions — костыль.

Одного сервера мало — что дальше

Как только приложений-копий больше одной, кто-то должен делить между ними трафик. Это и есть балансировщик: единственная точка входа, за которой живёт N одинаковых инстансов.

Он решает сразу две задачи: масштабирование (нагрузка делится) и отказоустойчивость (умерший инстанс выпадает из ротации, пользователи этого не видят).

L4 против L7

L4 (транспортный) L7 (прикладной)
Видит IP и порты HTTP целиком: путь, заголовки, куки
Умеет Разложить TCP-соединения Маршрутизацию по /api vs /static, ретраи, TLS
Цена Очень быстрый Дороже по CPU
Примеры LVS, облачные NLB nginx, HAProxy, Envoy, облачные ALB

Для веб-приложений почти всегда достаточно L7 — гибкость важнее последних микросекунд.

Алгоритмы в nginx

upstream app {
    least_conn;              # или пусто = round-robin
    server 10.0.0.11:8080 max_fails=3 fail_timeout=10s;
    server 10.0.0.12:8080 max_fails=3 fail_timeout=10s;
    server 10.0.0.13:8080 backup;
}

max_fails/fail_timeout — пассивный health-check: после трёх ошибок сервер на 10 секунд выпадает из ротации. Активные проверки (отдельный GET /healthz по таймеру) делают HAProxy, Envoy и облачные балансировщики — мёртвый инстанс убирается до того, как на него попал живой пользователь.

Sticky sessions — и почему их избегают

ip_hash и куки-привязка существуют для приложений, хранящих сессию в памяти процесса: пользователь должен возвращаться на «свой» сервер. Это работает, но ломает саму идею взаимозаменяемых инстансов: сервер умер — сессии с ним умерли, масштабирование перекошено.

Правильное направление — stateless-приложение: сессия в Redis или в подписанной куке, любой инстанс может обслужить любой запрос. Sticky sessions — временный мост для legacy, а не архитектура.