Load Balancer

Базовый System Design
≈ 2 мин чтения

Несколько экземпляров нужно превратить в один сервис

Если приложение запущено на нескольких серверах, клиенту не стоит самостоятельно выбирать конкретный экземпляр. Load Balancer принимает трафик на общей точке входа и распределяет запросы между доступными backend-узлами.

             +-> app-1
client -> LB +-> app-2
             +-> app-3

Так можно увеличивать пропускную способность горизонтально и выводить отдельные экземпляры из работы, не меняя адрес, которым пользуется клиент.

Как выбирать backend

Самый простой алгоритм — round robin: запросы по очереди отправляются разным экземплярам. Но в реальных системах выбор может учитывать количество активных соединений, вес узла или другие характеристики.

Не существует алгоритма, который всегда лучше остальных. Если запросы сильно отличаются по длительности, простое равномерное количество запросов ещё не гарантирует равномерную фактическую нагрузку.

Health checks исключают недоступные узлы

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

Важно различать «процесс запущен» и «экземпляр готов обслуживать запросы». Приложение может работать, но ещё загружать конфигурацию или не иметь доступа к обязательной зависимости. Поэтому проверка готовности должна отражать именно способность принимать реальный трафик.

L4 и L7

Балансировка может происходить на разных уровнях. L4-балансировщик принимает решение на основе сетевых соединений и транспортных данных, а L7-балансировщик понимает прикладной протокол, например HTTP, и может учитывать host, path или заголовки.

L7 даёт более гибкую маршрутизацию, но требует больше работы на уровне приложения. Выбор зависит от того, какие решения действительно нужно принимать на входе.

Балансировщик не исправляет состояние, привязанное к одному экземпляру. Если пользовательская сессия хранится только в памяти конкретного сервера, произвольное переключение на другой узел может сломать запрос. Это нужно учитывать в дизайне приложения, а не маскировать балансировкой.