Введение

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

Но как балансировщик нагрузки решает, какой сервер должен обрабатывать каждый запрос? Ответ кроется в алгоритмах балансировки нагрузки. Выбор правильного алгоритма может означать разницу между отзывчивым приложением и тем, что страдает от тайм-аутов и неравномерной нагрузки на серверы.

Это руководство рассматривает алгоритмы балансировки нагрузки в двух категориях: алгоритмы распределения, определяющие, как трафик распространяется по серверам, и методы persistence, обеспечивающие непрерывность сессии для stateful-приложений.

Почему выбор алгоритма важен

Правильный алгоритм балансировки нагрузки напрямую влияет на производительность приложения, пользовательский опыт и эффективность инфраструктуры:

40%
Снижение задержки

Улучшение времени отклика при оптимальном выборе алгоритма vs базовый round robin

Исследование производительности NGINX
высокая доступность
Цель аптайма

Корпоративное требование к доступности — лишь 52 минуты простоя в год

Отраслевой стандарт SLA
53%
Отказ пользователей

Пользователи уходят, если страница загружается дольше 3 секунд

Исследование производительности веб Google
3x
Прирост пропускной способности

Рост ёмкости при интеллектуальном распределении vs один сервер

Лучшие практики балансировки нагрузки

Категории алгоритмов

Алгоритмы балансировки нагрузки делятся на две основные категории, каждая из которых служит разным архитектурным потребностям:

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

Определяют, как трафик распространяется по серверам — последовательно, случайно или на основе метрик сервера в реальном времени, таких как соединения или время отклика.

Методы persistence

Обеспечивают непрерывность сессии, последовательно направляя запросы от одного клиента, URI или ID пользователя на один и тот же сервер.

На основе производительности

Продвинутые алгоритмы, учитывающие метрики состояния сервера — время отклика, глубина очереди, ошибки соединений — для оптимальных решений маршрутизации.

Гибридные подходы

Сочетают распределение с persistence или используют выбор по нескольким критериям (например, Fastest+) для изощрённых сценариев балансировки нагрузки.

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

Алгоритмы распределения сосредоточены на распространении трафика по пулу серверов. Выбор зависит от инфраструктуры серверов, характеристик запросов и требований к производительности.

Round Robin

Round Robin — простейший и наиболее широко развёрнутый алгоритм балансировки нагрузки. Работает точно так, как следует из названия: запросы распределяются по серверам в круговом, последовательном порядке. Первый запрос идёт на сервер 1, второй — на сервер 2, и так далее. После достижения последнего сервера цикл начинается заново.

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

Round Robin отлично подходит для однородных сред, где серверы имеют идентичные спецификации, а запросы относительно однородны — например, для обслуживания статического контента, простых API-эндпоинтов или stateless-микросервисов.

Round Robin: краткий обзор

АспектПодробности
Как работаетПоследовательное распределение: сервер 1 → сервер 2 → сервер 3 → повтор
Лучше всего дляОднородные серверы, равномерные нагрузки, stateless-приложения
Сильные стороныПростой, предсказуемый, нулевые вычислительные расходы, лёгкая отладка
СлабостиИгнорирует нагрузку сервера и различия в ёмкости
Сценарии использованияСтатический контент, edge-узлы CDN, stateless API

Weighted Round Robin

Weighted Round Robin расширяет базовый алгоритм, присваивая вес каждому серверу на основе его ёмкости. Серверы с более высокими весами получают пропорционально больше трафика. Если у сервера A вес 3, а у сервера B вес 1, сервер A обрабатывает три запроса на каждый один, обрабатываемый сервером B.

Этот алгоритм необходим для неоднородных серверных сред. Организации часто используют смесь оборудования — мощные новые серверы рядом со старыми машинами или облачные инстансы с разным количеством vCPU. Weighted Round Robin гарантирует, что 16-ядерный сервер обрабатывает больше трафика, чем 4-ядерный.

Веса обычно конфигурируются на основе ядер CPU, памяти или тестирования бенчмарками. Хотя этот алгоритм более гибкий, чем простой Round Robin, он всё же не учитывает нагрузку сервера в реальном времени — сильно взвешенный сервер под высокой нагрузкой будет продолжать получать трафик в зависимости от своего веса, а не текущей ёмкости.

Установка весов

Начните с весов, пропорциональных ядрам CPU или памяти. Например, если у сервера A 8 ядер, а у сервера B 4 ядра, присвойте веса 8 и 4 (или 2 и 1). Мониторьте и корректируйте на основе реальных метрик производительности — пропускной способности, времени отклика и частоты ошибок.

Least Connection

Least Connection использует динамический подход: каждый новый запрос идёт на сервер с наименьшим количеством активных соединений в этот момент. В отличие от Round Robin, этот алгоритм адаптируется к условиям в реальном времени — если один сервер обрабатывает много медленных запросов, новые запросы маршрутизируются на менее загруженные серверы.

Этот алгоритм особенно рекомендуется для серверов, обрабатывающих длительные сессии. Соединения с базами данных (SQL), сервисы каталогов (LDAP) и приложения с персистентными соединениями значительно выигрывают от распределения Least Connection.

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

Least Connection: краткий обзор

АспектПодробности
Как работаетМаршрутизирует на сервер с наименьшим количеством активных соединений
Лучше всего дляДлительные сессии, персистентные соединения, нагрузки баз данных
Сильные стороныАдаптируется к нагрузке в реальном времени, предотвращает перегрузку сервера, изящно обрабатывает медленные запросы
СлабостиНебольшие накладные расходы на отслеживание соединений
Сценарии использованияSQL-базы данных, LDAP-каталоги, WebSocket-приложения, API с длительно выполняющимися запросами

First

Алгоритм First использует уникальный подход: он отправляет весь трафик на первый сервер в пуле, пока этот сервер не достигнет своего максимального лимита соединений. Только тогда трафик идёт на следующий сервер.

Этот алгоритм полезен для конфигураций active-passive, где вы хотите, чтобы один основной сервер обрабатывал всю нагрузку, в то время как другие остаются в резерве. Он также ценен для лицензионных сценариев, где вы хотите максимально использовать один лицензированный сервер до задействования дополнительной ёмкости.

First обеспечивает предсказуемое поведение и упрощает устранение неполадок, поскольку вы знаете точно, какой сервер обрабатывает трафик. Однако он не обеспечивает преимуществ распределения нагрузки и полностью полагается на лимиты max connection для failover.

First: краткий обзор

АспектПодробности
Как работаетПервый сервер получает всю нагрузку, пока не будет достигнут max connections
Лучше всего дляActive-passive-конфигурации, оптимизация лицензий, предсказуемая маршрутизация
Сильные стороныПростой, предсказуемый, максимизирует использование одного сервера
СлабостиНет распределения нагрузки, зависит от конфигурации max connection
Сценарии использованияКонфигурации основной-резервный, лицензированное ПО, сценарии переполнения ёмкости

Random

Алгоритм Random выбирает серверы случайно для каждого входящего запроса. Однако, в отличие от чистой рандомизации, эта реализация учитывает как веса серверов, так и время отклика в своей вероятности выбора.

Этот взвешенный случайный подход обеспечивает статистическое распределение нагрузки, избегая предсказуемых шаблонов Round Robin. Со временем серверы получают трафик пропорционально своим весам, но случайный элемент предотвращает синхронизированные шаблоны запросов, которые могут вызывать периодические всплески нагрузки.

Случайный выбор особенно эффективен в больших пулах серверов, где закон больших чисел обеспечивает равномерное распределение. Он также полезен, когда вы хотите избежать проблемы «thundering herd», когда несколько клиентов одновременно нацеливаются на один и тот же сервер.

Random: краткий обзор

АспектПодробности
Как работаетСлучайный выбор сервера с учётом веса и времени отклика
Лучше всего дляБольших пулов серверов, избегания синхронизированных шаблонов
Сильные стороныПредотвращает thundering herd, статистически равномерное распределение, учитывает производительность
СлабостиМенее предсказуемый, чем Round Robin, может иметь краткосрочные дисбалансы
Сценарии использованияВысоконагруженные приложения, большие кластеры, кэш-серверы

Fastest

Алгоритм Fastest маршрутизирует запросы на сервер с лучшим временем отклика. Балансировщик нагрузки непрерывно мониторит производительность сервера и направляет трафик на тот сервер, который в данный момент отвечает быстрее всего.

Этот подход оптимизирует пользовательский опыт, гарантируя, что запросы идут на самый отзывчивый сервер. Он автоматически адаптируется к изменяющимся условиям — если сервер становится медленным из-за высокого CPU, нагрузки на память или внешних зависимостей, трафик смещается на более быстрые альтернативы.

Fastest идеален для приложений, чувствительных к задержке, где время отклика напрямую влияет на пользовательский опыт или бизнес-метрики. Потоки оформления заказа e-commerce, API реального времени и интерактивные приложения — все выигрывают от маршрутизации на основе времени отклика.

Fastest+

Fastest+ — самый изощрённый алгоритм, предлагающий двухуровневую оптимизацию с настраиваемыми критериями. Вы выбираете основную метрику (Opt-1) для выбора сервера и вторичную метрику (Opt-2), которая разрешает ничьи, когда у нескольких серверов равные основные значения.

Доступные критерии оптимизации включают: Least Response Time, Least Connection Time, Least Queue Time, Least Queues, Least Connection Error, Least Aborted Connections и Least Used Connections. Эта гибкость позволяет тонко настроить оптимизацию для характеристик вашей конкретной нагрузки.

Например, вы можете сконфигурировать Opt-1 как «Least Response Time» и Opt-2 как «Least Connection Error». Алгоритм сначала выбирает серверы с лучшим временем отклика, затем среди них выбирает тот, у которого наименьшее количество ошибок соединений. Этот многокритериальный подход справляется со сложными production-сценариями, где одиночных метрик недостаточно.

Опции оптимизации Fastest+

ОпцияОписаниеЛучше всего для
Least Response TimeСервер, отвечающий на запросы быстрее всегоПриложения, чувствительные к задержке
Least Connection TimeСервер, устанавливающий соединения быстрее всегоНагрузки с высокой текучкой соединений
Least Queue TimeСервер с кратчайшим ожиданием очереди запросовВсплесковые шаблоны трафика
Least QueuesСервер с наименьшим количеством запросов в очередиИзбегание накопления запросов
Least Connection ErrorСервер с наименьшим количеством неуспешных соединенийКритически надёжные приложения
Least Aborted ConnectionsСервер с наименьшим количеством отключений клиентовНагрузки с длительно выполняющимися запросами
Least Used ConnectionsСервер с наименьшим использованием соединенийПриложения с пулом соединений
Двухуровневый выбор

Fastest+ использует вторичный критерий (Opt-2) только когда несколько серверов имеют ничью по основному критерию (Opt-1). Это обеспечивает оптимальный выбор даже в однородных средах, где у серверов часто схожие характеристики производительности.

Методы persistence (самоперсистентные)

Методы persistence гарантируют, что связанные запросы от одного клиента, сессии или контекста всегда достигают одного и того же серверного backend. Это необходимо для stateful-приложений, хранящих данные сессии локально, а не в общем хранилище.

Source (IP persistence)

Source persistence использует хеш исходного IP-адреса клиента для выбора сервера. Значение хеша сочетается с весами серверов для определения маршрутизации. Один и тот же IP клиента всегда производит один и тот же хеш, обеспечивая согласованную маршрутизацию на один и тот же сервер.

Этот метод обеспечивает persistence сессии без необходимости в cookie или изменениях на уровне приложения. Все запросы с конкретного IP-адреса идут на один и тот же сервер, поддерживая любое состояние сессии, хранящееся на этом сервере.

У Source persistence есть ограничения в средах NAT, где несколько пользователей делят один IP-адрес, и с мобильными пользователями, которые могут менять IP-адреса. Для этих сценариев методы persistence на уровне приложения (URI, URL Param, HDR) обеспечивают лучшие результаты.

URI (persistence по пути)

URI persistence хеширует путь URI запроса для определения маршрутизации сервера. Текст URI до указанной длины (или до символа '?', если присутствуют query-параметры) хешируется и сочетается с весами серверов. Одни и те же URI всегда маршрутизируются на один и тот же сервер.

Опции конфигурации включают длину символов URI и глубину URI (количество сегментов пути для рассмотрения). Например, при глубине 2 и «/api/users/123», и «/api/users/456» будут хешировать тот же префикс «/api/users».

Этот метод отлично подходит для сценариев кэширования, где вы хотите, чтобы все запросы на один и тот же ресурс попадали на один и тот же сервер, максимизируя эффективность кэша. Он также полезен для шардированных backend, где разные шаблоны URI соответствуют разным партициям данных.

URL Param (persistence параметра)

URL Param persistence извлекает указанный параметр из URL (или тела POST) и использует его значение для маршрутизации сервера. Это обычно используется для отслеживания ID пользователей, сессионных токенов или других идентификаторов, специфичных для приложения. Одни и те же значения параметра всегда маршрутизируются на один и тот же сервер.

Вы конфигурируете имя URL-параметра для извлечения и опционально включаете проверку POST-параметра для отправки форм. Это обеспечивает persistence с учётом приложения, следующий за пользовательскими сессиями независимо от изменений IP-адреса.

Этот метод идеален для приложений, встраивающих идентификаторы сессии или пользователя в URL или данные форм. Он обеспечивает более надёжную persistence, чем методы на основе IP, для мобильных пользователей или находящихся за NAT.

HDR (persistence заголовка)

HDR persistence исследует указанный HTTP-заголовок в каждом запросе и маршрутизирует на основе его содержимого. Запросы с одинаковым значением заголовка всегда идут на один и тот же сервер. Вы конфигурируете, какое имя заголовка инспектировать.

Распространённые сценарии использования включают маршрутизацию на основе кастомных сессионных заголовков, API-ключей, идентификаторов арендатора в многотенантных приложениях или JWT-токенов. Это обеспечивает максимальную гибкость для приложений, управляющих собственными идентификаторами сессии.

HDR persistence особенно ценна для API-first архитектур и микросервисов, где состояние сессии управляется через заголовки, а не cookie. Она плавно интегрируется с системами аутентификации на основе токенов.

Hash (продвинутая кастомная persistence)

Hash persistence — самый мощный и гибкий метод, позволяющий строить кастомные ключи persistence практически из любого элемента в потоке трафика. Балансировщик нагрузки поддерживает хеш-таблицу (до 3 миллионов записей по умолчанию), сопоставляющую кастомные значения ключей с серверными backend, с настраиваемым истечением (по умолчанию 7 дней).

Ключ хеша может быть построен из сотен доступных переменных: IP и порт клиента, временные метки, поля SSL-сертификата, информация frontend, путь URL и метод, HTTP-заголовки, содержимое тела запроса, результаты обработки WAAP и многое другое. Вы можете комбинировать несколько переменных и применять функции трансформации для создания точно той логики persistence, которая требуется вашему приложению.

Например, вы могли бы создать ключ хеша, который: извлекает страну из IP клиента, проверяет, находится ли она в конкретном списке, затем сочетает это с именем пользователя из SSL-сертификата клиента. Все запросы, производящие одинаковое значение хеша из этой комбинации — что означает пользователей из одного региона с той же сертификатной идентичностью, — всегда будут направляться на один и тот же серверный backend. Это обеспечивает чрезвычайно гранулярный контроль persistence при поддержании состояния сессии приложения. Этот уровень настройки позволяет сценарии persistence, которых другие балансировщики нагрузки просто не могут достичь, делая его одной из отличительных возможностей TR7.

Строительные блоки ключа хеша

Ключ хеша может быть построен из любой комбинации этих элементов трафика:

КатегорияДоступные переменныеПример использования
Уровень сетиIP клиента, порт клиента, IP сервера, порт сервераГео-маршрутизация, привязка к сегменту сети
SSL/TLSCN сертификата, DN сертификата, SNI, шифр-сюитаМаршрутизация на основе сертификата клиента, сценарии mTLS
HTTP-запросМетод, путь, URL, query-параметры, заголовок HostМаршрутизация на основе контента, версионирование API
HTTP-заголовкиЛюбое значение заголовка (Authorization, X-Tenant-ID и т. д.)Многотенантная маршрутизация, привязка к API-ключу
Тело запросаPOST-параметры, поля JSON, данные формPersistence на основе транзакций
КонтекстВремя, дата, имя frontend, решение WAAP, страна GeoIPМаршрутизация на основе времени, маршрутизация соответствия
Выражения ключа хеша

Ключи хеша поддерживают функции трансформации: манипуляция строками (substring, regex), кодирование (base64, URL encode), поиск (страна GeoIP, ASN) и условную логику. Сочетайте их для построения сложных правил persistence. Например: «Если клиент из стран ЕС И имеет валидный клиентский сертификат, постройте ключ хеша из CN сертификата; иначе постройте из заголовка Authorization» — гарантируя, что запросы, соответствующие одним условиям, всегда достигают одного и того же серверного backend.

Сравнение методов persistence

МетодНа основеКонфигурацияЛучше всего для
SourceХеш IP-адреса клиентаНет (автоматически)Простые веб-приложения, унаследованные системы
URIХеш пути запросаДлина URI, глубина URIКэширование, маршрутизация контента, шардированные backend
URL ParamЗначение URL/POST-параметраИмя параметра, опция проверки POSTОтслеживание сессии, маршрутизация по пользователю
HDRЗначение HTTP-заголовкаИмя заголовкаAPI-аутентификация, многотенантные приложения, JWT-маршрутизация
New CookieCookie, управляемый LBИмя cookie, max-idle, max-lifeБез изменений приложения, контроль тайм-аута сессии
Current CookieСуществующий cookie приложенияИмя cookie для отслеживанияИспользование существующих сессий приложения
HashВыражение кастомного ключаПеременные ключа, функции, 3 млн записей, TTL 7 днейСложная многофакторная persistence, максимальная гибкость

Руководство по выбору алгоритма

Выбор правильного алгоритма зависит от ваших конкретных требований. Это сравнение подчёркивает ключевые компромиссы:

АлгоритмУчёт нагрузкиСложностьPersistenceОсновной сценарий использования
Round RobinНетМинимальнаяНетОднородные stateless-нагрузки
Weighted Round RobinСтатический (веса)НизкаяНетСмешанные ёмкости серверов
Least ConnectionДинамический (соединения)СредняяНетДлительные сессии, базы данных
FirstНетМинимальнаяНетActive-passive, оптимизация лицензий
RandomДинамический (время отклика)НизкаяНетБольшие кластеры, кэш-серверы
FastestДинамический (время отклика)СредняяНетПриложения, чувствительные к задержке
Fastest+МультикритериальныйВысокаяНетСложные production-среды
SourceЧерез весаНизкаяДа (IP)Простая persistence сессии
URIЧерез весаСредняяДа (путь)Кэширование, маршрутизация контента
URL ParamЧерез весаСредняяДа (ID пользователя)Отслеживание сессии пользователя
HDRЧерез весаСредняяДа (заголовок)Маршрутизация API, многотенантные

Выбор алгоритма

Используйте алгоритмы распределения, когда

  • Приложение stateless или использует общее хранилище сессий
  • Нужно распределить нагрузку по пулу серверов
  • У серверов разные ёмкости (используйте Weighted)
  • Оптимизация времени отклика критична (используйте Fastest/Fastest+)

Используйте методы persistence, когда

  • Приложение хранит данные сессии локально на серверах
  • Серверные сервисы шардированы по пользователю или контенту
  • Эффективность кэширования требует согласованной маршрутизации
  • Используется аутентификация на основе токена или заголовка

Используйте Fastest+, когда

  • Одна метрика не охватывает вашу цель оптимизации
  • Нужна логика разрешения ничьи для однородных серверов
  • Важны и производительность, и надёжность
  • Сложная production-среда с разнообразными нагрузками

Лучшие практики реализации

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

01

Внедрите надёжные проверки состояния

Сконфигурируйте активные проверки состояния, верифицирующие функциональность приложения, а не только TCP-связность. Сервер, отвечающий на пинги, но возвращающий ошибки 500, должен быть удалён из ротации.

02

Мониторьте и корректируйте веса

Для взвешенных алгоритмов пересматривайте назначения весов ежеквартально или после изменений инфраструктуры. Тестируйте серверы под реалистичной нагрузкой для определения точных соотношений ёмкости.

03

Выбирайте persistence мудро

Проектируйте приложения stateless, когда возможно, храня сессии во внешних хранилищах, таких как Redis. Если persistence требуется, выбирайте метод, лучше всего соответствующий вашему идентификатору сессии (IP, URI, параметр или заголовок).

04

Тестируйте сценарии failover

Регулярно тестируйте сбои серверов для обеспечения изящного failover. Верифицируйте, что поведение алгоритма корректно, когда серверы удаляются и заново добавляются в пул.

05

Используйте Fastest+ для сложных сценариев

Когда одноментрические алгоритмы не удовлетворяют ваши потребности, сконфигурируйте Fastest+ с основным и вторичным критериями. Начните с Least Response Time как Opt-1 и Least Connection Error как Opt-2.

Часто задаваемые вопросы

Да, методы persistence (Source, URI, URL Param, HDR) уже включают веса серверов в свои решения маршрутизации. Это означает, что вы получаете и привязку сессии, и распределение с учётом ёмкости. Выбор на основе хеша взвешивается согласно конфигурациям серверов.

Используйте Fastest, когда время отклика — ваша единственная забота, а серверы имеют явно разные характеристики производительности. Используйте Fastest+, когда нужен более нюансированный выбор — например, оптимизация по времени отклика, но предпочтение серверов с меньшим количеством ошибок, когда времена отклика схожи.

Когда персистентный сервер становится недоступным, запросы перенаправляются на другой сервер на основе перераспределения хеша алгоритма persistence. Данные сессии на упавшем сервере теряются, если ваше приложение не использует внешнее хранилище сессий. Проверки состояния гарантируют быстрое удаление упавших серверов из пула.

Least Connection как отдельный алгоритм маршрутизирует на сервер с наименьшим количеством активных соединений. «Least Used Connections» в Fastest+ учитывает использование соединений относительно ёмкости сервера, делая его более подходящим для неоднородных серверных сред.

Для мобильных приложений избегайте Source (IP) persistence, поскольку мобильные устройства часто меняют IP-адреса. Используйте URL Param persistence с ID пользователя или сессионным токеном или HDR persistence с заголовком аутентификации. Эти методы следуют за сессией пользователя независимо от изменений сети.

Заключение

Алгоритмы балансировки нагрузки фундаментальны для доставки приложений, однако часто упускаются из виду во время архитектурных решений. Правильный алгоритм обеспечивает равномерное использование серверов, оптимальное время отклика и устойчивый failover, в то время как неправильный выбор может создавать горячие точки, деградировать производительность и усложнять устранение неполадок.

Для большинства production-сред начните с Least Connection для динамических нагрузок или Weighted Round Robin для статического распределения ёмкости. По мере созревания ваших возможностей мониторинга исследуйте Fastest+ для многокритериальной оптимизации. Выбирайте методы persistence на основе вашей стратегии управления сессиями — Source для простоты или URI/URL Param/HDR для маршрутизации с учётом приложения.

Интеллектуальное распределение трафика

Балансировщик нагрузки TR7 поддерживает все основные алгоритмы, включая продвинутый Fastest+ с многокритериальной оптимизацией, плюс гибкие опции persistence для маршрутизации с учётом сессий. Оптимизируйте доставку приложений с балансировкой нагрузки корпоративного класса.

Изучить ADC