В тесте среднее время обработки запроса на сервере стабильно, но сквозная задержка растёт с нагрузкой. Какой механизм следует искать первым?
В первую очередь следует искать очередь перед ограниченным ресурсом: пулом соединений, потоков, процессов, слотовым лимитом или внешним сервисом. Время фактической обработки запроса остаётся прежним, но растёт время ожидания до её начала, поэтому увеличивается сквозная задержка.
Разделение задержки на время обслуживания и время ожидания выросло из задач анализа вычислительных систем с ограниченными ресурсами. Одной только длительности обработки недостаточно: при росте конкуренции запросы могут проводить значительную часть времени в очередях.
Такой подход нужен, чтобы не путать медленную бизнес-логику с перегруженным ресурсом. Он связывает результаты нагрузочного теста с моделями массового обслуживания и помогает объяснять нелинейный рост задержек около предела пропускной способности.
Если анализировать только серверное время обработки, можно ошибочно решить, что приложение работает стабильно. При этом пользователи уже ждут свободный поток, соединение с базой данных или разрешение на выполнение операции.
Неверный вывод приводит к оптимизации не того участка системы. Например, сокращение времени обработки запроса на несколько процентов не устранит задержку, если основное время теряется в очереди перед пулом фиксированного размера.
Сквозную задержку полезно разложить так: время ожидания до обслуживания + время обслуживания + сетевые и прочие накладные задержки. Если серверная обработка стабильна, а сквозная задержка растёт, увеличивается один из компонентов ожидания или внешних накладных расходов.
Типичный механизм таков: число одновременно прибывающих запросов приближается к пропускной способности ресурса. Свободные слоты заканчиваются, новые запросы выстраиваются в очередь, а измеренное время обработки уже выполняющегося запроса не меняется.
Проверять нужно не только загрузку CPU. Важны длина и время ожидания в пулах, число активных и занятых ресурсов, количество установленных соединений, задержки внешних зависимостей, отказы по тайм-аутам, а также временная корреляция этих показателей со сквозной задержкой.
Ограничение метода состоит в том, что стабильное серверное время не доказывает наличие именно одной очереди. Причиной могут быть сеть, балансировщик, клиентский генератор или другая внешняя зависимость, поэтому вывод подтверждают распределёнными метриками и трассировкой.
Компромисс при увеличении размера пула очевиден: оно может уменьшить ожидание до определённого предела, но одновременно повысить конкуренцию за базу данных, CPU или внешнюю систему. Поэтому устранение очереди на одном уровне способно лишь переместить узкое место дальше по цепочке.
Предположим, при росте нагрузки сквозная задержка API увеличилась с 200 до 900 миллисекунд. При этом измеренное время выполнения серверной операции оставалось около 180 миллисекунд, а пул соединений к базе данных был почти постоянно полностью занят.
Рассматривались три варианта. Оптимизация SQL могла уменьшить время обслуживания, но не устраняла ожидание свободного соединения. Увеличение пула обещало снизить очередь, однако могло перегрузить базу данных. Снижение нагрузки скрывало бы симптом, но не решало проблему пропускной способности.
Выбрали поэтапное увеличение пула вместе с контролем загрузки базы данных и измерением времени ожидания соединения. Это подтвердило механизм: после расширения пула задержка снизилась, пока база данных не приблизилась к своему пределу; дальнейшее увеличение пула эффекта не дало.
Ответ: Узким местом может быть ресурс, не связанный с вычислительной загрузкой процесса: база данных, сетевое соединение, диск, внешний сервис, лимит потоков или семафор. Кроме того, одно ядро может быть перегружено при невысокой средней загрузке всех ядер, а процесс может большую часть времени ждать ввода-вывода. Поэтому среднее значение CPU по всей машине нельзя использовать как доказательство отсутствия очереди.
Ответ: Нужно сопоставить клиентскую сквозную задержку с серверными временными отметками, метриками очередей и задержками отдельных участков маршрута. Если сервер фиксирует стабильное время обработки, а время до начала обработки растёт, вероятна внутренняя очередь. Если серверные интервалы стабильны, но различие между клиентскими и серверными измерениями увеличивается, следует проверять сеть, балансировщик или клиентский генератор.
Ответ: Пул ограничивает конкуренцию и тем самым защищает зависимость от чрезмерного числа параллельных операций. Его расширение может сократить локальное ожидание, но увеличить нагрузку на базу данных или внешний сервис, вызвать блокировки, исчерпать память и повысить суммарное время обработки. Поэтому размер пула выбирают по наблюдаемой пропускной способности всей цепочки, а не по желанию устранить одну конкретную очередь.