ТестированиеНагрузочное тестированиеИнженер по нагрузочному тестированию

Каким образом повторное использование HTTP соединений меняет результаты нагрузочного теста?

Каким образом повторное использование HTTP-соединений меняет результаты нагрузочного теста?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Повторное использование HTTP-соединений обычно уменьшает измеряемую задержку и повышает достижимую пропускную способность, потому что устраняет или сокращает затраты на установку TCP-соединения и TLS-сеанс. Если тест постоянно создаёт новые соединения, он измеряет не только обработку запросов сервисом, но и стоимость подключения.

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

Исторический контекст

Ранние модели взаимодействия с веб-сервисами часто создавали отдельное соединение для каждого запроса. По мере роста числа запросов это стало неэффективно: повторялись сетевое установление соединения, согласование защищённого канала и распределение ресурсов на стороне клиента и сервера.

Механизмы keep-alive и постоянных соединений появились как способ снизить эти повторяющиеся накладные расходы. В нагрузочном тестировании это привело к необходимости отдельно учитывать стоимость установления соединения и стоимость передачи запроса по уже готовому каналу.

Постановка проблемы

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

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

Подробное решение

При новом TCP-соединении возникают затраты на установление транспортного канала. Для защищённого протокола добавляется TLS-рукопожатие. Эти операции увеличивают задержку первого запроса и потребляют CPU, память и ресурсы таблиц соединений на клиенте, балансировщике и сервере.

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

Изменение режима соединений влияет не только на задержку. При частом создании соединений растёт число рукопожатий, увеличивается потребление CPU и может исчерпаться диапазон клиентских портов или лимиты на открытые соединения. При чрезмерно долгом удержании соединений, наоборот, возрастает потребление памяти и число занятых слотов, а распределение запросов между экземплярами сервиса может стать менее равномерным.

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

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

Ситуация из практики

Команда сравнила две версии сервиса. В тесте первой версии каждый запрос открывал новое защищённое соединение, а во второй клиент переиспользовал соединения. Вторая версия показала заметно меньший p95, и первоначально это приняли за улучшение серверной обработки.

Рассматривались два варианта. Можно было оставить новый режим соединений и объявить регрессию устранённой, но это смешивало бы эффект клиента с изменениями сервиса. Можно было полностью отключить повторное использование, что упростило бы сравнение стоимости подключения, но перестало бы отражать рабочий профиль пользователей.

Выбрали два согласованных прогона: с реалистичным повторным использованием соединений — для пользовательского SLA, и с одинаковой политикой новых соединений — для сравнения внутренней обработки версий. Дополнительно измерили число установленных соединений, TLS-рукопожатий и загрузку CPU. Выяснилось, что бизнес-обработка почти не изменилась, а основная разница в p95 была вызвана количеством подключений; это предотвратило ошибочный вывод о производительности версии.

Что кандидаты часто упускают

  1. Следует ли всегда использовать постоянные соединения, чтобы получить более производительный тест?

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

  1. Почему усреднение всех запросов может скрыть влияние установления соединения?

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

  1. Может ли повторное использование соединений изменить не только клиентскую, но и серверную производительность?

Да. При reuse снижается число рукопожатий и операций создания соединений, поэтому уменьшается нагрузка на TLS-обработку, сетевой стек и структуры учёта соединений. Однако слишком длительное удержание каналов может занять серверные лимиты и ухудшить доступность ресурсов для новых клиентов. Поэтому нужно оценивать компромисс по задержке, CPU, числу активных соединений, отказам подключения и времени ожидания свободного ресурса.