Нагрузочное тестирование: где инфраструктура ломается первой
Нагрузочное тестирование инфраструктуры отвечает не на вопрос «сколько запросов в секунду держит сервис», а на вопрос, что именно отказывает первым. Пул соединений к базе исчерпывается раньше, чем заканчивается процессорное время: приложение начинает ждать свободный слот, время ответа растёт нелинейно, а внешне это выглядит как «сервис работает, но медленно». Точки отказа под нагрузкой почти никогда не совпадают с тем, что показывает мониторинг в спокойном режиме.
Второй типичный слой — дисковые операции и очереди. Запись журнала, синхронный сброс на диск, накопление задач в очереди фоновых обработчиков: пока запас велик, всё выглядит ровно, но при приближении к пределу пропускной способности очередь растёт быстрее, чем её успевают разбирать. Деградация под пиковой нагрузкой идёт каскадом — медленный диск тормозит обработчик, обработчик занимает соединение, соединение исчерпывает пул.
Третий слой — лимиты внешних сервисов: квоты на вызовы, ограничения на число одновременных запросов, таймауты на стороне партнёра. Узкое место в контуре часто находится именно там, за границей нашей зоны контроля, и без замера его не видно: сервис отвечает быстро, пока лимит не выбран, а после — часть запросов получает отказ.
Поэтому замер строится как поиск предела пропускной способности с постепенным ростом нагрузки, а не как один прогон на максимуме. Разбираем, как выстроить такой замер и что он показывает про запас вашей инфраструктуры.
Измеримый эффект: доля отказов, запас ёмкости, время восстановления
Эффект от нагрузочного тестирования фиксируем не по средней загрузке процессора, а по поведению контура на пределе. Профиль нагрузки поднимаем ступенями с постоянной частотой запросов: ровный поток на wrk2 показывает, где начинает расти время ответа, а не только где заканчивается пропускная способность.
Каждую позицию снимаем до и после изменений на одном и том же профиле — иначе сравнение ничего не доказывает.
- Доля отказов под нагрузкой — ошибки по превышению времени ожидания, отказы зависимостей и ответы с признаком перегрузки считаем раздельно. Класс «сервис лёг целиком под пиком» после настройки ограничителей и очередей больше не воспроизводится.
- Запас ёмкости контура — известно, на какой кратности к рабочему трафику начинается рост времени ответа и где проходит аварийный порог.
- Время восстановления сервиса — прогон на отказ: сколько занимает возврат трафика, какие шаги делает дежурная смена и что проверяет после.
- Предсказуемое масштабирование — точка добавления экземпляров привязана к конкретной метрике, а не к интуиции дежурного.
- Устранённый класс отказов — фиксируем, какой именно сбойный сценарий закрыт и какие проверки не дадут ему вернуться.
По каждому пункту в отчёте остаются графики до и после, пороги и условия прогона. На них дежурная смена опирается при следующем росте трафика, а не на догадки.
Форматы нагрузочного тестирования: режимы, стенды, ограничения
Профиль нагрузки задаёт не только сценарий — долю чтений и записей, длительность пика, поведение при отказах, — но и то, где прогон вообще допустимо запускать. Формат выбирают по трём осям: изоляция от продуктивного контура, достоверность замеров и цена ошибки, если тест заденет живых пользователей. Ниже — варианты, между которыми реально выбирают, и ограничения каждого.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Изолированный стенд | Проверка гипотез и регресс после изменений в коде или конфигурации | Не воспроизводит сетевые задержки, поведение балансировщика и профиль соседних сервисов |
| Реплика продуктивного контура | Нужны реалистичные замеры перед выкаткой на боевой | Расходится с боевым по объёму данных и характеру трафика, требует постоянной поддержки |
| Прогон на продуктивном контуре | Разово, в окно низкой нагрузки, для валидации ёмкости | Риск для пользователей, нет повторяемости, замер смешивается с реальным трафиком |
| Непрерывный контроль нагрузки | Фоновые прогоны малой интенсивности, канареечные замеры после релиза | Слабый сигнал на предельных режимах, нужны эталонные значения и автоматическое сравнение |
У метода замера есть собственные ограничения, о которых стоит помнить при чтении отчёта. Генератор нагрузки сам потребляет ресурсы и на высоких профилях становится узким местом раньше, чем испытуемый сервис: цифры падают, хотя система ещё держит. Первые секунды прогона искажены прогревом кэшей и пулов соединений, поэтому участок разгона в расчёт не берут, а среднее время ответа скрывает хвост распределения — смотрят перцентили.
Выбранный формат фиксируем в регламенте: профиль, длительность, прогрев, критерий годности и стенд. Тогда результаты сравнимы между прогонами и релизами, а рост задержек виден до того, как его заметят пользователи.
Этапы работ: от аудита контура до передачи регламентов
Нагрузочное тестирование начинается не с запуска генератора, а с инвентаризации контура: где стоят балансировщики, какие лимиты пулов соединений и таймаутов заданы, как ведут себя внешние зависимости. Без этой карты прогон измеряет предел самого генератора или одного случайно угаданного параметра, а не системы.
Дальше работа идёт этапами — каждый закрывает отдельную гипотезу и оставляет артефакт, который можно перепроверить.
- Аудит контура. Снимаем схему связей, лимиты соединений, места хранения состояния; отделяем узлы для изолированных замеров от тех, что проверяются только совместно.
- Сценарии нагрузки. Согласуем профили: ровная нагрузка, ступенчатый рост до отказа, короткие пики. Фиксируем целевую интенсивность и допустимую задержку на p95 и p99.
- Подготовка тестовых данных. Наполняем стенд сопоставимым объёмом записей и распределением ключей — иначе кэш и индексы ведут себя иначе, чем на реальных данных.
- Сборка стенда и калибровка генератора. Проверяем, что инструмент нагрузки не упирается в собственные ресурсы, и добавляем прогрев перед замерами.
- Прогоны и наблюдение. Снимаем метрики приложения и хостов одновременно и меняем по одной переменной — так узкое место определяется однозначно.
- Проверка результата. Повторяем профиль и сверяем разброс между прогонами: воспроизводимость важнее единичного красивого значения.
- Передача регламента. Отдаём сценарии, конфигурации, дашборды и порядок повторных проверок после изменений в контуре.
На выходе у команды заказчика остаётся процедура, а не разовый отчёт: перед каждым изменением контура прогон повторяется по тем же сценариям, и регресс видно до выхода в рабочий режим.
Что остаётся у вас: конфигурации, схемы, политики, отчёты
После сдачи проекта контур остаётся в вашем репозитории и вашей инфраструктуре — мы не держим его «у себя» и не привязываем к своим серверам. Ниже то, чем разработчики и дежурная смена пользуются без нашего участия: от готовых профилей нагрузки до порогов, по которым прогон считается проваленным.
- Набор конфигураций нагрузки — параметризованные сценарии под разный профиль трафика: короткие всплески, длинная полка, ступенчатый рост. Запуск одной командой, без ручной правки скриптов под каждый прогон.
- Схема контура и точек замера — что и где измеряется: генераторы, балансировщик, приложение, база, кэш. Сразу видно, на каком звене теряется время, а не только итоговое «стало медленнее».
- Пороговые значения нагрузки — интенсивность, доля ошибок и задержка на 95-м и 99-м процентиле, при которых прогон считается проваленным, и по которым настраивается автоматическая остановка.
- Политики доступа к тестовым данным — обезличенная копия базы, правила её обновления и жёсткий запрет на запись в продуктивный контур во время прогона.
- Инструкция для дежурной смены — порядок запуска, разрешённые окна, что смотреть при деградации, как прервать прогон и откатить внесённые изменения.
- Шаблон отчёта по прогону — графики задержек, распределение ошибок, узкое звено, сравнение с предыдущей сборкой в одинаковых условиях.
- Регламент регрессии — какие сценарии обязательны перед выкаткой и при каком результате релиз блокируется автоматически.
Всё это описано так, чтобы новый инженер в команде воспроизвёл прогон по документации, не задавая нам вопросов.
Кейс: как сняли деградацию под пиковой нагрузкой
Сервис с суточной неравномерностью трафика: под вечерним пиком доля ошибок доходила до 6–7%, а время ответа росло в разы от рабочего уровня. Сбои были непостоянными — контур держался на кэше и запасе по мощностям, поэтому дежурная смена узнавала о деградации из обращений в поддержку, а не из алертов.
Собрали воспроизводимый профиль нагрузки на wrk2 — с постоянной интенсивностью вместо «залпов», чтобы повторные прогоны были сопоставимы между собой. Узкое место оказалось не в приложении: под пиком выбирался пул соединений к базе, а агрессивные повторы запросов добивали её и превращали локальную задержку в каскадный отказ. Увеличили пул, ограничили повторы с задержкой, тяжёлые фоновые задачи вынесли за пределы пикового окна.
| Метрика под пиком | До работ | После |
|---|---|---|
| Доля ошибок | 6–7% | до 0,2% |
| Время ответа | рост в 5–8 раз | в пределах 1,5× от нормы |
| Обнаружение деградации | обращение в поддержку | алерт по задержке и насыщению пула |
| Повторяемость прогонов | разброс до 40% | в пределах 10% |
После устранения деградации прогнали нагрузку ещё трижды с шагом по интенсивности — картина воспроизводилась, каскада не возникало. Пороги алертов привязали к задержке и заполнению пула, поэтому дежурный видит проблему раньше клиентов, а сам профиль нагрузки остался в регрессионном контуре и запускается перед крупными выкатками.
Что делать, если контур работает и ронять его нельзя
На живом контуре нагрузочный прогон не отличается от обычного трафика — вопрос только в том, кто первым заметит, что система на пределе. Поэтому проверку строят вокруг бюджета, выше которого деградация становится необратимой: растут очереди, время ответа уходит за порог, а остановка занимает минуты вместо секунд.
Щадящий режим прогона задаётся тремя ограничителями: скорость запросов, число одновременных соединений и общая длительность. Интенсивность держим постоянной, без ступенчатого разгона — так видно, где именно начинается деградация, а не где она уже случилась. Обязателен автоматический стоп: как только 95-й или 99-й процентиль времени ответа превышает порог, нагрузка снимается сама, до того как это заметят пользователи.
Часть прогонов уместнее проводить в окно обслуживания — там снимается вопрос влияния на людей, можно поднять интенсивность и проверить поведение при отказе узлов. На живом трафике остаётся малая доля: один узел из группы, временно выведенный из балансировки, либо небольшая доля запросов через отдельный маршрут.
Перед этим контур прогоняют на копии с тем же профилем данных и теми же лимитами, что в рабочей среде. Генератор вроде wrk2 держит ровный поток запросов и корректно меряет задержки под нагрузкой — средние значения здесь бесполезны, важен хвост распределения.
Предел системы снимают не одним большим прогоном, а серией коротких, с заранее известной точкой остановки. Так проверка остаётся безопасным экспериментом, а не инцидентом.
Технические сомнения: изоляция, данные, достоверность замеров
Перед стартом нагрузочного тестирования у команды заказчика возникают одни и те же вопросы: где гонять нагрузку, откуда брать данные и можно ли верить цифрам. Разбираем их заранее — на старте это дешевле, чем в отчёте.
Как прогон изолируется от продуктивного контура?
Под тест разворачиваем отдельный стенд — копию продуктивной топологии с собственной базой, кэшем и очередями. Генератор нагрузки живёт в своей подсети с квотами на ресурсы, поэтому не забирает мощность у рабочих сервисов, а трафик не идёт через внешние балансировщики: пользователи не получают ни лишних соединений, ни отказов.
Откуда берутся тестовые данные и персональные сведения?
Берём обезличенную выборку: имена, адреса и контакты заменяем синтетикой, но сохраняем структуру и пропорции — объём таблиц, долю активных профилей, соотношение чтения и записи. Если выгрузка невозможна, генерируем набор по согласованному профилю. Персональные сведения не покидают контур заказчика и не попадают в отчёты.
Насколько достоверны замеры и воспроизводится ли результат?
До замеров прогреваем систему и снимаем фоновые метрики, чтобы отделить нагрузку от собственной активности сервисов. В отчёт попадает режим прогона: число соединений, профиль запросов, длительность, состав стенда. Повторный прогон в тех же условиях даёт расхождение в пределах нескольких процентов, иначе ищем причину, а не усредняем.
Что нужно от вас для старта и как мы вернёмся с оценкой
Чтобы план работ был реалистичным, а не «средним по отрасли», нужен минимум входных данных. Собираем их на первом разговоре — обычно 40–60 минут с вашим инженером или владельцем сервиса, после чего фиксируем договорённости письменно и возвращаемся с оценкой и планом.
- Сценарий, критичный для бизнеса: какие маршруты запросов и в какой пропорции дают реальный трафик, что считаем успешным ответом.
- Профиль нагрузки: пиковая и средняя интенсивность, число одновременных клиентов, длительность прогона и скорость нарастания.
- Целевые показатели: допустимое время ответа на высоких перцентилях, доля ошибок, при которой прогон считается провальным, порог деградации для остановки.
- Тестовый контур, сопоставимый с рабочим: адреса, учётные данные, ограничения на внешние сервисы и способы их подмены.
- Ограничения и окна: когда нагрузку можно подавать, с кем согласуем, кто со стороны эксплуатации может нажать «стоп».
- Точка контакта: ответственный с вашей стороны и канал, где оперативно решаем вопросы по ходу прогонов.
Дальше порядок такой: разбираем данные, возвращаемся с планом работ — сценарии, выбор генератора нагрузки (для ровной интенсивности и точных перцентилей берём wrk2, для коротких всплесков — wrk), метрики, роли и окна прогонов. План согласуем с вашими инженерами и только после этого начинаем.







