Балансировка нагрузки повышает производительность, когда запросы можно параллельно обслуживать на нескольких сопоставимых экземплярах, а проблема связана с перегрузкой отдельных узлов или неравномерным трафиком. Балансировщик распределяет работу, исключает из пула неготовые экземпляры и помогает эффективнее использовать доступные ресурсы.
Балансировщик не ускоряет медленный SQL-запрос, не увеличивает пропускную способность единственного primary-сервера базы данных и не исправляет CPU-bound обработку внутри каждого экземпляра приложения. Если все узлы ждут одну внешнюю систему, добавление новых реплик меняет точку входа, но сохраняет прежнее узкое место.
Эффект проверяют по latency, p95 и p99, throughput, error rate, CPU, memory, сетевым показателям, числу активных соединений и длине очередей. Средняя загрузка серверов сама по себе не подтверждает улучшение: при среднем отклике 150 мс отдельные запросы могут получать p99 в 3 секунды из-за очередей или зависшей зависимости.
Когда балансировка нагрузки повышает производительность, а когда не меняет ситуацию
Производительность растет при наличии нескольких экземпляров, которые способны выполнять одну и ту же операцию, и при возможности равномерно распределить между ними входящий поток. В этой схеме балансировщик снижает локальное насыщение, а горизонтальное масштабирование добавляет вычислительную емкость.
Если пропускную способность ограничивает общий ресурс, балансировка дает ограниченный результат. К таким ресурсам относятся единственный сервер базы данных, пул соединений фиксированного размера, брокер с заполненной очередью, файловое хранилище с исчерпанными IOPS и синхронный внешний API.
Какие признаки указывают, что проблема находится в распределении нагрузки
Проблема часто находится в распределении трафика, когда состояние экземпляров заметно различается:
- один backend использует 90-100% CPU, а два соседних держатся на уровне 20-30%;
- на одном узле растет локальная очередь запросов, хотя суммарная мощность группы не достигла предела;
- p95 и p99 существенно различаются между экземплярами;
- клиенты повторно подключаются к одному узлу из-за IP hash, sticky sessions или особенностей DNS-кэширования;
- часть узлов получает больше тяжелых операций, хотя количество запросов между ними выглядит одинаковым;
- после временного отключения перегруженного экземпляра его нагрузка переходит на остальные, а задержка уменьшается только при равномерном перераспределении.
Диагноз подтверждают метрики по каждому backend, а не только показатели балансировщика. В журнале полезно сохранять идентификатор выбранного узла, время ожидания соединения, время обработки и код ответа. Такой набор позволяет отделить задержку на маршрутизацию от задержки приложения.
Начать поиск причины можно с пошаговой диагностики производительности по CPU, памяти, дискам, очередям и сети. Для балансировки этот порядок полезен тем, что показывает состояние каждого экземпляра и его зависимостей.
Почему добавление балансировщика не ускоряет медленную зависимость
Представим три экземпляра API, которые отправляют запросы на одну базу данных. Каждый экземпляр способен обработать 200 запросов в секунду, но база принимает только 300 запросов в секунду. После добавления балансировщика прикладной слой сможет принять больше входящих запросов, однако база начнет накапливать очередь, а p99 вырастет.
Та же картина возникает при следующих ограничениях:
- блокировки строк или таблиц задерживают транзакции;
- медленные SQL-запросы расходуют соединения и CPU базы данных;
- пул соединений приложения исчерпан, поэтому новые запросы ждут свободный слот;
- внешнее API отвечает синхронно и имеет фиксированный лимит запросов;
- каждый экземпляр выполняет тяжелое CPU-bound преобразование, а входной поток уже равномерно распределяется;
- общее хранилище не выдерживает рост числа параллельных операций.
Балансировщик может снизить локальную перегрузку и повысить устойчивость прикладного слоя. Он не создает дополнительную производительность для ресурса, который остается общим и ограниченным. Сначала находят узкое место по метрикам, затем выбирают действие: индексы и переписывание запроса, увеличение пула с учетом возможностей базы, кэширование, асинхронная обработка, репликация или изменение протокола взаимодействия.
Для первичной локализации bottleneck пригодится разбор узких мест в CPU, RAM, storage, сети и приложении. Балансировка должна дополнять такой анализ, а не заменять его.
С чего начать: базовая линия, профиль нагрузки и критерии успеха
До смены алгоритма или добавления экземпляров зафиксируйте базовую линию. Без нее сравнение строится на субъективном ощущении скорости и не показывает, какая часть системы изменилась.
В базовую линию включают версию приложения и балансировщика, конфигурацию backend-группы, объем данных, размер пулов соединений, число клиентов, профиль запросов, длительность теста и состояние зависимостей. Каждый эксперимент должен менять один существенный параметр.
Метрики, по которым оценивают балансировку нагрузки и производительность
| Метрика | Что показывает | Как интерпретировать |
|---|---|---|
| Средняя latency | Среднюю задержку ответа | Подходит для общей оценки, но скрывает редкие медленные запросы |
| p95 и p99 | Хвост распределения задержки | Показывают опыт 5% и 1% самых медленных запросов |
| Throughput | Объем успешно обработанных запросов или задач за секунду | Сравнивается вместе с latency и ошибками |
| Error rate | Долю ошибок, таймаутов и отказов | Рост throughput при росте ошибок не считается улучшением |
| CPU и memory | Насыщение вычислительных ресурсов | Сравниваются по каждому узлу и по общей группе |
| Активные соединения | Количество текущих клиентов и запросов | Помогает оценивать Least Connections и лимиты пулов |
| Длина очереди | Объем работы, ожидающей обработки | Устойчивый рост указывает на превышение пропускной способности |
| Сетевые показатели | Задержки, потери, retransmit и заполнение канала | Отделяют сетевое ограничение от проблем приложения |
Среднее значение latency может оставаться стабильным при ухудшении p99. Например, 990 запросов из 1000 укладываются в 100 мс, а 10 ждут по 10 секунд. Среднее значение будет около 199 мс, хотя для части пользователей сервис практически недоступен.
Метрики используют совместно. Throughput без error rate показывает неполную картину. Низкий CPU при высоком p99 часто указывает на ожидание сети, базы данных, блокировки или ограничение количества соединений. Низкий memory usage не доказывает отсутствие проблем с диском или очередью.
При сравнении нескольких размеров группы полезны scaling curves, кривые масштабирования. На графике сопоставляют число экземпляров, throughput, p95/p99 и стоимость ресурсов. Идеальная линейная зависимость встречается редко: после насыщения общей зависимости добавление узлов увеличивает задержку быстрее, чем пропускную способность.
Как провести сравнение до и после изменения конфигурации
- Сохраните рабочую конфигурацию балансировщика, приложения и зависимостей.
- Опишите профиль нагрузки: долю чтения и записи, размер запросов, долю длинных операций, число одновременных клиентов и частоту повторов.
- Проведите несколько одинаковых прогонов на штатной нагрузке и на пике. Первый короткий прогон используйте для прогрева кэшей, в измерение его не включайте.
- Зафиксируйте throughput, среднюю latency, p95, p99, ошибки, таймауты, CPU, memory, сеть, активные соединения и очереди.
- Измените один параметр, например алгоритм с Round Robin на Least Connections.
- Повторите тест при той же версии приложения, том же объеме данных и сопоставимом входном потоке.
- Проверьте распределение запросов по backend-узлам, включая тяжелые и долгие операции.
- Отдельно отключите один экземпляр и убедитесь, что оставшаяся группа выдерживает нагрузку без неконтролируемого роста очередей.
Разовые замеры не подходят для вывода о производительности. Нагрузка должна быть воспроизводимой, а длительность теста достаточной для проявления утечек памяти, заполнения очередей, изменения кэшей и накопления репликационной задержки.
Алгоритмы балансировки нагрузки: как выбрать схему распределения запросов
Алгоритм выбирают по стоимости запроса, длительности соединения, различиям между узлами и требованиям к состоянию. Равное число запросов не гарантирует равную работу: один запрос кэшируется за 5 мс, другой выполняет сложную транзакцию за 2 секунды.
Round Robin и Weighted Round Robin для однотипных запросов
Round Robin отправляет запросы на узлы по циклу. При трех одинаковых экземплярах последовательность может выглядеть так: A, B, C, A, B, C. Алгоритм дает предсказуемый результат при stateless-приложении, близкой производительности узлов и похожем времени обработки операций.
Главное ограничение связано с неодинаковой стоимостью запросов. Пять тяжелых операций подряд могут занять один узел надолго, хотя счетчик запросов между серверами останется равным.
Weighted Round Robin учитывает вес узла. При весах 2, 1 и 1 первая машина получит примерно 50% запросов, остальные по 25%, если запросы сопоставимы по стоимости. Веса подходят для серверов с разным числом CPU, объемом памяти или сетевой емкостью.
Вес не заменяет измерение. Узел с большим CPU может упираться в диск или базу данных раньше более слабого узла. После изменения веса проверяют p95, p99 и фактическое насыщение, а не только долю трафика.
Least Connections и Least Response Time для долгих и неравномерных запросов
Least Connections выбирает узел с наименьшим количеством активных соединений. Схема полезна для долгих HTTP-запросов, WebSocket и операций с неодинаковой длительностью, когда занятые соединения достаточно хорошо отражают текущую работу.
Количество соединений не всегда равно потреблению CPU или работе с базой. Одно соединение может выполнять тяжелый запрос, а десятки других почти ничего не делать. Алгоритм способен направить новый поток на узел с малым числом соединений, но уже заполненным пулом базы данных.
Least Response Time выбирает экземпляр по измеренной задержке, иногда с учетом числа активных соединений. Такой подход быстрее реагирует на деградацию, но качество решения зависит от окна измерения, частоты обновления статистики и состава запросов. Медленный внешний API может сделать все запросы конкретного узла долгими, хотя локальный CPU свободен.
Для обоих алгоритмов нужны корректные health checks, разумные таймауты и защита от кратковременных выбросов. Узел с несколькими быстрыми ответами не должен мгновенно получать весь поток после короткого восстановления. Помогают slow start, ограничение доли трафика и проверка readiness.
Hash-based распределение: IP hash, cookie hash и ключ маршрутизации
Hash-based схема вычисляет ключ и детерминированно выбирает backend. Ключом может быть IP клиента, cookie, идентификатор пользователя, tenant или другой бизнес-признак.
- IP hash сохраняет маршрут при повторных запросах с одного адреса, но крупная NAT-сеть может создать горячий узел.
- Cookie hash удобен для привязки браузерной сессии, однако требует корректной работы с cookie при отказе или выводе узла.
- Hash по бизнес-ключу сохраняет локальность данных конкретного пользователя или tenant, но неравномерные ключи вызывают перекос.
Изменение состава backend-группы может перераспределить большую часть ключей. Consistent hashing снижает объем перемещений, но не отменяет проблему горячих ключей и отказов. Hash выбирают ради локальности или сохранения состояния, а не как универсальный способ ускорить обработку.
Sticky sessions: что это и почему привязка клиента к узлу ограничивает масштабирование
Sticky sessions, или session affinity, направляют последующие запросы клиента к одному backend-узлу. Привязка строится по cookie, IP, идентификатору сессии или другому ключу.
Схема упрощает работу приложения, которое держит HTTP-сессию в локальной памяти. Цена такой простоты выражается в менее равномерной загрузке, сложном выводе узла из эксплуатации и менее надежном failover. При отказе закрепленного экземпляра клиент теряет локальное состояние или проходит повторную аутентификацию.
В каких случаях sticky sessions оправданы
Временная привязка допустима в нескольких сценариях:
- legacy-приложение хранит сессию в памяти процесса и пока не готово к переработке;
- команда постепенно переводит сервис на общий session storage;
- протокол использует длительное соединение с локальным контекстом;
- короткая миграция требует сохранить маршрут ограниченной группы клиентов.
Для привязки задают документированный TTL, например 15 минут, и описывают поведение после отказа узла. Мониторинг должен показывать количество сессий на каждом экземпляре, долю трафика по узлам, время их жизни и число повторных аутентификаций.
Sticky sessions опасны при автоматическом масштабировании. Новый экземпляр может долго оставаться почти пустым, пока старые клиенты продолжают обращаться к прежним узлам. При draining новые сессии переводят на другие экземпляры, а активным соединениям дают завершиться в установленный срок.
Как убрать зависимость от конкретного экземпляра приложения
Для stateless-архитектуры состояние выносят из процесса приложения:
- сессии хранят в отказоустойчивом Redis или базе данных;
- для коротких данных используют подписанный токен, если размер и требования безопасности это допускают;
- загруженные файлы помещают в общее объектное или сетевое хранилище;
- временные данные не записывают на локальный диск контейнера без отдельной схемы сохранения;
- повторные запросы делают идемпотентными с помощью ключа операции;
- локальные кэши считают ускорителем, а не единственным хранилищем состояния.
Общий storage становится новой зависимостью. Для него проверяют лимиты соединений, задержку, отказоустойчивость, резервирование и поведение при потере сети. Перенос сессий в Redis не решает задачу, если один Redis-сервер сам превращается в точку отказа.
Health checks, таймауты и очереди запросов: как сохранить стабильность под нагрузкой
Балансировщик должен отправлять трафик на узлы, которые готовы принять рабочий запрос. Для этого нужны health checks, таймауты, лимиты соединений, ограниченные очереди и контролируемая политика повторов.
Чем readiness-проверка отличается от проверки доступности процесса
Liveness отвечает на вопрос: процесс работает или завис. Readiness отвечает на другой вопрос: способен ли экземпляр сейчас обслужить рабочий запрос.
Процесс может вернуть успешный ответ на liveness, но оставаться неготовым в следующих случаях:
- приложение еще прогревает кэш;
- нет соединения с критичной базой данных;
- исчерпан пул соединений или локальный лимит файлов;
- идет восстановление после перегрузки;
- узел выводится из работы и должен перестать получать новые запросы.
Readiness-проверка должна отражать способность обработать реальный тип запроса, но не создавать заметную дополнительную нагрузку. Тяжелый SQL-запрос при каждом health check может сам ухудшить состояние базы. Частоту, таймаут и число последовательных ошибок задают с учетом времени восстановления приложения.
Проверяйте полный путь: балансировщик, TLS, приложение и критичную зависимость. При этом liveness не стоит связывать со всеми внешними системами, иначе краткий отказ базы может вызвать перезапуск здоровых процессов и усилить аварию.
Когда очередь помогает, а когда превращает задержку в таймауты
Короткая очередь сглаживает временный всплеск, если входная скорость вскоре возвращается ниже пропускной способности. При устойчивом превышении очереди только переносят отказ во времени: растут latency, memory и число таймаутов.
Пример: сервис обрабатывает 100 запросов в секунду, а клиенты присылают 130. Разница в 30 запросов в секунду будет накапливаться, пока очередь не достигнет лимита. Увеличение лимита дает больше времени, но не повышает throughput.
Для оценки очередей полезно применять закон Литтла: L = lambda * W, где L, среднее число запросов в системе, lambda, скорость поступления, W, среднее время пребывания. При 100 запросах в секунду и среднем времени обработки 0,5 секунды в системе находится около 50 запросов. Если среднее ожидание вырастает до 2 секунд, при том же потоке их станет около 200.
Рабочая политика включает:
- ограниченный размер очереди;
- отказ при переполнении с понятным кодом, например 429 или 503;
- rate limiting для клиентов, которые создают избыток работы;
- backpressure, передачу сигнала отправителю о необходимости снизить скорость;
- асинхронные задачи для операций, которым не нужен синхронный ответ;
- отдельные лимиты для критичных и фоновых операций.
Выбор лимита связывают с SLO и временем, которое клиент готов ждать. Очередь на 30 секунд может быть неприемлема для API с целевым p99 в 1 секунду, но допустима для фоновой обработки, если клиент получает подтверждение постановки задачи.
Практические схемы работы с очередями, backpressure и метриками собраны в инструкции по устойчивости автоматических систем под пиковыми нагрузками.
Почему ретраи без бюджета усиливают отказ
Повторный запрос увеличивает входную нагрузку в момент, когда зависимость уже работает нестабильно. Если балансировщик, клиентский SDK и сервис каждый выполняют по три попытки, одна исходная операция способна породить до 27 обращений к нижнему слою.
Политика retry должна включать:
- общий retry budget, долю запросов, которую разрешено повторять;
- ограничение числа попыток;
- exponential backoff, увеличение паузы между попытками;
- jitter, случайное смещение времени повтора;
- проверку идемпотентности операции;
- единое решение о том, какой слой выполняет retry.
Запрос на чтение чаще можно повторить после сетевого сбоя, а повтор платежа или записи без idempotency key способен создать дубликат. При превышении бюджета система должна быстро вернуть контролируемую ошибку или передать работу в асинхронную очередь.
Балансировка для веб-сервисов, API, баз данных и внутренних платформ
Одинаковый термин скрывает разные задачи. Веб-сервис и API чаще масштабируют добавлением stateless-экземпляров. База данных требует маршрутизации с учетом консистентности и состояния реплик. Внутренняя платформа в Kubernetes разделяет маршрутизацию, проверку готовности и управление емкостью.
Веб-сервисы и API: stateless-слой как основной кандидат для горизонтального масштабирования
При stateless-модели любой экземпляр может принять любой запрос. Сессии и файлы хранятся вне процесса, операции имеют понятные таймауты, а пул соединений рассчитан на суммарное количество реплик.
Для коротких HTTP-запросов часто начинают с Round Robin и сравнивают его с Least Connections. Для WebSocket учитывают длительность соединений и задают лимит на число активных каналов. Streaming-ответы требуют отдельного read timeout, иначе несколько долгих клиентов надолго займут соединения и исказят работу алгоритма.
При масштабировании API проверяют четыре слоя:
- балансировщик, его CPU, число соединений и время установления TLS;
- приложение, его p95/p99, CPU, memory и локальные очереди;
- пул соединений к базе и кэшу;
- rate limiting, кэширование и наблюдаемость по tenant или endpoint.
Пять новых реплик могут увеличить число одновременных соединений к базе в пять раз, если каждая получает собственный пул. Лимиты рассчитывают для всей группы, а не копируют одинаковые значения без проверки.
Для веб-проектов и внутренних сервисов можно использовать облачную инфраструктуру с VDS, базами данных и Kubernetes, например Timeweb Cloud. Выбор площадки не отменяет проверки пулов соединений, SLO, отказа узла и поведения общих зависимостей.
Базы данных: почему read balancing не заменяет проектирование хранилища
Балансировка чтения между репликами помогает распределить read-only запросы, если реплики успевают получать изменения и приложение допускает их задержку. Запросы, которым нужна актуальная запись сразу после изменения, направляют на primary или на узел с подтвержденной консистентностью.
Репликационная задержка должна быть отдельной метрикой. Если приложение отправляет запись на primary, а следующее чтение попадает на реплику с отставанием 2 секунды, пользователь может увидеть старое состояние.
Распределение подключений не устраняет ограничения базы:
- единый write primary остается пределом для записи;
- блокировки продолжают задерживать транзакции;
- медленные запросы требуют анализа плана и индексов;
- IOPS и объем памяти могут ограничивать throughput раньше CPU;
- слишком большой пул соединений создает конкуренцию и расход памяти.
Балансировщик базы должен учитывать роль узла, режим read-only, задержку репликации и процедуру failover. Переключение на новый primary требует проверки потери подтвержденных транзакций, DNS или service discovery и повторного открытия пулов.
Внутренние платформы и Kubernetes: где заканчивается Service и начинается управление емкостью
Kubernetes Service дает стабильную точку доступа и распределяет соединения между подходящими Pod. Ingress или Gateway добавляет маршрутизацию HTTP, TLS и правила публикации. Эти механизмы выбирают адресата, но не создают вычислительную емкость.
За количество реплик и доступный ресурс отвечают другие механизмы:
- readiness probes исключают Pod, который еще не готов принимать трафик;
- requests и limits задают планирование и верхние ограничения ресурсов;
- HPA меняет число реплик по CPU, memory или пользовательским метрикам;
- autoscaling узлов добавляет емкость кластеру, когда Pod некуда разместить;
- PodDisruptionBudget ограничивает число одновременно недоступных реплик при обслуживании кластера;
- draining при rollout дает активным соединениям завершиться перед остановкой Pod.
Четыре реплики API не помогут, если база выдерживает два параллельных тяжелых запроса, а HPA реагирует после заполнения очереди. Для настройки нужны нагрузочные тесты, метрики зависимостей и проверка времени старта нового Pod.
Признаки того, что балансировщик скрывает архитектурную проблему
Смена алгоритма и увеличение числа узлов не должны считаться лечением сами по себе. Если общая зависимость насыщена, балансировщик лишь меняет место, где запрос начинает ждать.
Симптомы общей точки насыщения
Ищите корреляцию между масштабированием прикладного слоя и состоянием общих ресурсов:
- после роста числа реплик увеличивается нагрузка на базу, кэш или брокер;
- latency растет одновременно на всех backend-узлах;
- все экземпляры получают ошибки получения соединений;
- растет I/O wait при невысоком CPU;
- очередь брокера увеличивается быстрее, чем число обработанных задач;
- внешнее API возвращает rate limit или начинает отвечать медленнее;
- исчерпываются квоты файлового хранилища, сети или облачной платформы.
Проверяйте метрики в одной временной шкале. Рост CPU API через 30 секунд после роста очереди базы может показывать последствия ожидания и повторов, а не первичную причину.
Ошибки конфигурации, которые создают ложное ощущение высокой доступности
- Health check проверяет только открытый TCP-порт и отправляет запросы на неготовый процесс.
- Read timeout превышает срок действия клиентского запроса, поэтому очередь продолжает расти после фактического отказа клиента.
- При rollout нет draining, и активные соединения обрываются вместе с остановкой узла.
- Агрессивные ретраи повторяют одну операцию на нескольких уровнях.
- Очередь не имеет лимита и расходует память до OOM.
- Sticky sessions закрепляют крупного клиента за одним экземпляром.
- Сессии или файлы лежат на локальном диске и исчезают при переносе запроса.
- Autoscaling добавляет реплики после роста p99, когда зависимость уже перегружена.
- Отказ одного backend-узла не проверялся при реальном числе соединений.
Для каждого симптома формулируйте первичную гипотезу и проверку. При росте нагрузки на базу сравните число реплик, размер пулов и количество активных соединений. При одинаково медленном ответе всех узлов проверьте внешние вызовы, блокировки, сеть и состояние хранилища.
Сетевые задержки, потери пакетов, проблемы DNS и TLS часто выглядят как медленная работа приложения. Отделить их помогает порядок диагностики влияния сети на производительность.
Практический порядок внедрения и проверки балансировки нагрузки
Безопасная схема начинается с измерений и заканчивается проверкой отказа. Каждый шаг должен иметь критерий успеха и план возврата к прежней конфигурации.
Чек-лист перед изменением конфигурации
- Зафиксирована базовая линия: latency, p95, p99, throughput, ошибки, CPU, memory, сеть и очереди.
- Метрики разделены по backend-узлам, endpoint, tenant и типу операции.
- Определены SLO для штатной и пиковой нагрузки.
- Понятно, где находится bottleneck и какую гипотезу проверяет изменение.
- Выбран алгоритм с учетом длительности запросов, различий между узлами и состояния сессии.
- Readiness отделена от liveness, а health checks не создают заметную нагрузку.
- Заданы connect, read и request timeouts, лимиты соединений и размер очередей.
- Описаны retry budget, backoff, jitter и условия идемпотентности.
- Проверено, выдержат ли база данных, кэш, брокер, хранилище и внешние API рост параллелизма.
- Для sticky sessions описаны TTL, draining и восстановление после отказа.
- Подготовлен план отката с сохраненной предыдущей конфигурацией.
- Известен владелец изменения и канал наблюдения за метриками после переключения.
Какие сценарии нужно протестировать до production
- Штатная нагрузка. Сравните распределение запросов и хвостовую latency при обычном профиле трафика.
- Пиковая нагрузка. Увеличивайте поток постепенно, фиксируя точку насыщения и длину очереди.
- Длинные запросы. Проверьте Least Connections, лимиты соединений и read timeout на операциях с длительной обработкой.
- Отказ одного узла. Остановите backend и измерьте время исключения из пула, ошибки клиентов и нагрузку на оставшиеся экземпляры.
- Медленный backend. Создайте задержку на одном узле и проверьте, перестает ли балансировщик направлять туда основной поток.
- Недоступность зависимости. Отключите тестовую базу, кэш или внешний API и убедитесь, что readiness, таймауты и backpressure ограничивают каскад.
- Rollout с draining. Обновите узел при активных WebSocket, streaming и обычных HTTP-запросах.
- Восстановление. Верните зависимость и узел, проверьте выход очереди на нулевой или штатный уровень без лавины ретраев.
Для каждого сценария записывайте latency, p95, p99, throughput, ошибки, распределение трафика, активные соединения, CPU, memory и поведение очередей. После теста сохраняйте конфигурацию, версии компонентов и параметры окружения. Один и тот же алгоритм может дать разные результаты при другом размере ответа, составе запросов или объеме данных.
Практический порядок действий выглядит так: определить SLO и профиль нагрузки, найти узкое место, включить наблюдаемость, убрать локальное состояние там, где это возможно, выбрать алгоритм, настроить readiness и draining, ограничить очереди и ретраи, провести нагрузочный тест, проверить отказы, затем перевести трафик поэтапно и сравнить показатели с базовой линией.
Вопрос-ответ
Увеличивает ли балансировщик пропускную способность сам по себе
Нет. Балансировщик помогает равномернее использовать существующие и добавленные экземпляры. Пропускная способность растет, когда за ним есть свободная емкость, а запросы можно выполнять параллельно. При единой медленной базе или внешнем API общий предел сохраняется.
Нужны ли sticky sessions для авторизации пользователей
Обычно нет. При токеновой аутентификации или общем session storage любой экземпляр может проверить пользователя. Привязка нужна, когда приложение зависит от локальной HTTP-сессии, локального контекста длительного соединения или другого состояния конкретного узла.
Какая метрика важнее: средняя latency или p99
Нужны обе. Средняя latency показывает общий уровень задержки, а p95 и p99 раскрывают хвост, где видны очереди, перегрузка и неравномерное распределение. Интерпретируйте их вместе с throughput и error rate: уменьшение latency ценой роста ошибок не считается улучшением.