Балансировщики нагрузки: алгоритмы и L4/L7

Балансировщик — это диспетчер, который раскидывает входящие запросы по пулу серверов.

Балансировщик нагрузки (load balancer) — компонент, распределяющий входящий трафик между несколькими серверами, чтобы ни один не был перегружен, а падение узла не ломало сервис.

Без балансировщика горизонтальное масштабирование невозможно: клиенту нужен один адрес, а за ним должно стоять много серверов. Балансировщик даёт клиенту единую точку входа и прячет за ней пул. Заодно он убирает мёртвые узлы из ротации через health-чеки.

Алгоритмы распределения

АлгоритмКак работаетКогда уместен
Round-robinпо очереди: 1, 2, 3, 1, 2, 3…серверы одинаковы, запросы однородны
Weighted round-robinмощным узлам больше запросовсерверы разной мощности
Least connectionsна узел с меньшим числом активных соединенийзапросы разной длительности
IP / URL hashхеш от ключа → всегда тот же сервернужна привязка клиента к узлу (липкость)
Least response timeна самый быстрый сейчас узелразная и меняющаяся нагрузка

L4 против L7

Балансировщики различают по уровню модели OSI, на котором они принимают решение.

СвойствоL4 (транспортный)L7 (прикладной)
ВидитIP и порт (TCP/UDP)содержимое HTTP: URL, заголовки, cookie
Решение поадресу и портупути запроса, домену, заголовкам
Скоростьочень быстро, дёшевомедленнее: разбирает пакет
Умеетпросто пробросить соединениемаршрут /api → одни серверы, /img → другие; SSL-терминация

L7 умнее: может направить /video на серверы с видео, а /api — на API-кластер, разорвать TLS, переписать заголовки. L4 проще и быстрее, когда содержимое не важно. На практике часто стоят оба слоя.

Health-чеки и failover

Балансировщик периодически опрашивает узлы (например, GET /health). Если узел не ответил несколько раз — его выводят из ротации, и трафик идёт на живые. Когда узел «выздоровел» — возвращают. Это и есть базовая отказоустойчивость на уровне балансировки.

LB --health--> server-1  ✓ ok
LB --health--> server-2  ✗ нет ответа → исключить из пула
LB --health--> server-3  ✓ ok
Новые запросы идут только на server-1 и server-3.

Sticky sessions (липкость)

Если сервис хранит состояние сессии в памяти конкретного узла, балансировщик можно настроить так, чтобы клиент всегда попадал на тот же сервер (через cookie или hash IP). Это костыль: ломает равномерность и мешает падению узла переживаться. Правильнее — сделать сервис stateless, а сессию хранить во внешнем хранилище (об этом — следующий урок).

Сам балансировщик — единая точка отказа?

Да, поэтому в проде их ставят минимум два (active-passive или active-active) с общим виртуальным IP, который переезжает на живой при падении. Дублируйте и сам балансировщик.

Итог

  • Балансировщик — единая точка входа и условие горизонтального масштабирования.
  • L4 быстр и прост (IP/порт), L7 умён (видит HTTP, маршрутизирует по пути).
  • Health-чеки убирают мёртвые узлы; sticky sessions — костыль, лучше stateless.
Проверьте себя
1. Чем L7-балансировщик отличается от L4?
AL7 работает только с UDP
BL7 видит содержимое HTTP (URL, заголовки) и может маршрутизировать по пути, L4 — только по IP/порту
CL4 умнее и медленнее, чем L7
DМежду ними нет разницы
2. Какой алгоритм лучше подходит, когда запросы сильно разной длительности?
ARound-robin
BLeast connections — отправляет на узел с наименьшим числом активных соединений
CСлучайный выбор
DВсегда первый сервер
3. Почему sticky sessions считают костылём?
AОни ускоряют систему
BОни ломают равномерность и мешают переживать падение узла; лучше сделать сервис stateless
CОни не работают с HTTP
DИх запрещают балансировщики
Поддержать проект