Как работает балансировщик нагрузки и какие типы используются
Что проверяют
Различаете ли вы уровни балансировки и алгоритмы распределения, и понимаете ли, что балансировщик держит состояние (проверки здоровья, липкость) и сам обязан быть отказоустойчивым.
Как отвечать
- Задача: принять трафик, раздать его на пул одинаковых бэкендов и убрать из пула нездоровые узлы, получив масштабирование и отказоустойчивость.
- L4 работает с TCP и UDP: пробрасывает соединение, не знает про URL и заголовки, дёшев и подходит любому протоколу. L7 разбирает HTTP: маршрутизирует по хосту и пути, терминирует TLS, повторяет идемпотентные запросы, применяет лимиты. Типовые инструменты: Nginx, HAProxy, Envoy, облачные ALB и NLB.
- Алгоритмы: round robin для одинаковых узлов и дешёвых запросов, weighted round robin по мощности узла, least connections для долгих соединений и вебсокетов, хеш по ключу ради локальности кэша. Consistent hashing нужен, чтобы добавление узла не переразметило все ключи.
- Проверки здоровья бывают активные (запрос на
/health) и пассивные (узел выводится по ошибкам живого трафика). Liveness и readiness разделяют: узел на прогреве трафик получать не должен. - Сам балансировщик не должен быть единственной точкой отказа: пара узлов с общим VIP через keepalived и VRRP, anycast или несколько A-записей. DNS-балансировка ограничена TTL и кешами резолверов, быстро увести трафик с упавшего узла она не умеет.
- В микросервисах часть балансировки уезжает на клиента: Spring Cloud LoadBalancer, gRPC, сайдкар Envoy. Ribbon давно в архиве, предлагать его не стоит.
Где спотыкаются
Начинают с деления на аппаратные и программные решения. Рамка устарела: на практике почти везде софт на обычных серверах либо управляемый балансировщик облака.
Считают round robin честным по нагрузке. Он честен по числу запросов, а не по их стоимости, и один тяжёлый эндпоинт перекашивает пул.
Называют IP hash способом сохранить сессию, не вспоминая ни про NAT, ни про то, что смена числа узлов меняет раскладку целиком.
Забывают про health checks и graceful shutdown: без вывода узла из пула перед остановкой каждый деплой теряет часть запросов.