Балансировщики нагрузки: алгоритмы и 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.