Нагрузочное тестирование: как заранее узнать, что система не выдержит
Сайт лежит первые сорок минут распродажи, а команда в чате выясняет, база это или приложение. Проблема почти всегда известна заранее — просто её никто не искал, пока трафик был обычным. Мы в Code Pilots готовим системы к пикам и делаем аудит кода и архитектуры; нагрузочный тест — самый быстрый способ увидеть, где конструкция сложится.
Если совсем коротко. Нагрузочное тестирование отвечает на три вопроса: сколько система держит сейчас, где она ломается первой и что происходит при перегрузке — деградирует плавно или падает целиком.
Ценность даёт не сам прогон, а профиль нагрузки, снятый с реальных данных, и наблюдение за внутренностями системы во время теста. Без этого получается красивый график, из которого нельзя сделать ни одного вывода.
В статье
Что проверяет нагрузочный тест
Под общим названием живут пять разных проверок, и они отвечают на разные вопросы.
| Вид теста | Что делает | На какой вопрос отвечает |
|---|---|---|
| Нагрузочный | Держит ожидаемую нагрузку заданное время | Справляемся ли мы с плановым трафиком |
| Стрессовый | Наращивает нагрузку до отказа | Где предел и как именно система ломается |
| Пиковый | Резкий всплеск за секунды | Переживём ли рассылку, эфир, старт продаж |
| Тест стабильности | Умеренная нагрузка часами | Есть ли утечки памяти и накопительные эффекты |
| Объёмный | Работа на больших объёмах данных | Что будет, когда в базе не сто тысяч записей, а десять миллионов |
Чаще всего заказывают первый, а полезнее всего оказываются второй и четвёртый: предел системы и её поведение на длинной дистанции — то, чего не видно в обычной эксплуатации. Архитектурная сторона вопроса — как проектировать систему, чтобы она держала нагрузку, — разобрана в материале про высоконагруженные системы.
Когда его делают
Есть несколько моментов, когда тест окупается почти гарантированно.
Перед сезонным пиком. Распродажа, старт продаж билетов, приём заявок в конкретную дату, отчётный период в корпоративной системе.
Перед крупной рекламной кампанией. Особенно если планируется телевизионная или наружная реклама: там трафик приходит всплеском, а не ровным потоком.
После смены архитектуры. Переезд на новую базу, разделение монолита, смена хостинга или контура — поведение под нагрузкой меняется непредсказуемо.
При росте бизнеса. Подключение новых филиалов, магазинов, партнёров, каналов продаж: объёмы вырастают ступенькой.
После инцидента. Чтобы убедиться, что исправление действительно помогло, а не просто совпало с падением трафика.
Профиль нагрузки
Главный документ теста и то, что отличает осмысленную проверку от «постучим по сайту».
Считается он из реальных данных аналитики. Берём пиковый день за последний год, смотрим распределение по часам, вычисляем количество запросов в секунду в самый плотный час. Затем закладываем запас: обычно двух-трёхкратный к прошлогоднему пику, если бизнес растёт, или под конкретный план кампании.
Дальше — сценарии с весами. Реальные пользователи не долбят одну страницу: часть смотрит каталог, часть ищет, часть кладёт в корзину, единицы оформляют заказ. Пропорции берутся из аналитики, а не выдумываются: тест, где все поголовно оформляют заказы, ломает базу там, где в жизни узко не бывает.
В профиль обязательно входят: доля новых и вернувшихся пользователей (у первых пустой кэш), распределение по устройствам, доля запросов к тяжёлым разделам, фоновые процессы, которые в это же время работают в системе — выгрузки, обмены, регламентные задания.
Метрики результата
| Метрика | Что показывает | Как читать |
|---|---|---|
| Время отклика p95 и p99 | Опыт большинства и опыт худших | p95 — то, что чувствуют пользователи; расхождение с p99 говорит о нестабильности |
| Пропускная способность | Сколько запросов в секунду реально обработано | Сравнивать с целевым RPS профиля |
| Доля ошибок | Отказы под нагрузкой | Рост ошибок раньше роста времени ответа — признак исчерпания пулов |
| Точка деградации | Момент, когда время ответа начинает расти | Обычно наступает задолго до полного отказа |
| Точка отказа | Когда система перестаёт отвечать | Показывает запас прочности |
| Поведение после снятия нагрузки | Восстанавливается ли система сама | Если нет — в проде это означает ручной перезапуск ночью |
Среднее время ответа в отчёте смотреть бессмысленно: при половине запросов по 100 мс и половине по 5 секундах среднее выглядит приемлемо, а половина пользователей уже ушла.
Стенд и данные
Результат теста ровно настолько достоверен, насколько стенд похож на прод.
Мощность. Стенд вдвое слабее прода даёт цифры, которые нельзя пересчитать линейно: узкие места на разных конфигурациях разные. Идеальный вариант — копия прода, приемлемый — та же архитектура в уменьшенном масштабе с явной оговоркой в отчёте.
Данные. Объём базы влияет на всё: запрос, мгновенный на десяти тысячах записей, на десяти миллионах уходит в секунды. Нужны обезличенные данные сопоставимого объёма, а не пустая тестовая база.
Внешние системы. Платёжный шлюз, служба доставки, учётная система — в тесте их обычно заменяют заглушками с реалистичными задержками. Иначе вы либо нагружаете чужой продакшн, либо получаете нереально быстрые ответы.
Кэши и прогрев. Первый прогон после старта всегда медленнее. Либо прогреваем систему заранее, либо честно считаем этот эффект частью сценария — как при массовом заходе новых пользователей.
Стенд стоит денег, и это нормальная строка бюджета: копия прода на несколько дней в облаке обходится в разы дешевле часа простоя в пик. Оптимальная схема — поднимать среду под прогон и гасить после, а конфигурацию хранить как код, чтобы следующий раз занимал часы, а не недели.
Что мерить внутри системы
Ошибка большинства прогонов: смотрят только на клиентские метрики. Тест говорит «медленно», а причина остаётся неизвестной.
Во время прогона снимаются: загрузка процессора и памяти по каждому сервису, длина очередей, использование пулов соединений к базе, время самых тяжёлых запросов, попадания в кэш, паузы сборки мусора, глубина очередей сообщений, задержки ответов внешних систем.
Практика: чаще всего первым исчерпывается не процессор, а пул соединений к базе или количество рабочих процессов приложения. Внешне это выглядит как рост времени ответа и ошибки таймаутов, а по графикам процессора кажется, что «ресурсов полно».
Типовые узкие места
| Место | Как проявляется | Что обычно помогает |
|---|---|---|
| Запросы к базе без индексов | Время ответа растёт нелинейно с объёмом данных | Индексы, переписывание запросов, денормализация |
| N+1 запрос | Одна страница делает сотни обращений к базе | Пакетная загрузка связанных данных |
| Отсутствие кэша | Одинаковые тяжёлые вычисления на каждый запрос | Кэш ответов и справочных данных с понятным сроком жизни |
| Синхронные вызовы внешних систем | Тормозит чужой сервис — тормозит всё | Очередь, таймауты, обработка в фоне |
| Пулы и лимиты | Ошибки при свободных процессоре и памяти | Настройка пулов, ограничение одновременных запросов |
| Блокировки | Растёт время записи, появляются взаимные блокировки | Пересмотр транзакций, уменьшение области блокировки |
| Тяжёлая отчётность на боевой базе | Всё встаёт в момент выгрузки | Вынос отчётности в отдельную витрину |
Большая часть этих проблем решается на уровне кода и конфигурации, а не покупкой серверов. Мы обычно разбираем их вместе с архитектурой при работе над веб-продуктами: добавить мощности можно всегда, но если узкое место в блокировках, лишние серверы ничего не изменят.
Внешние ограничители
Ваша система может быть готова, а пик всё равно провалится — из-за того, что от вас не зависит.
Платёжный шлюз с лимитом запросов в секунду, служба доставки с медленным расчётом стоимости, учётная система, которая обрабатывает заказы по одному, СМС-провайдер с очередью, антифрод-сервис с задержкой в секунду.
Что делать: заранее выяснить лимиты у каждого партнёра, договориться о повышении на период пика, предусмотреть поведение при отказе — очередь вместо отказа клиенту, отложенный расчёт доставки, ручное подтверждение позже. Тест обязательно должен включать сценарий «внешний сервис отвечает за пять секунд или не отвечает вовсе».
Инструменты
Выбор инструмента — далеко не главное решение в проекте, но пара практических соображений есть.
Для веб-сервисов чаще всего берут k6, JMeter, Gatling или Locust; в российских командах распространён Яндекс.Танк с Pandora. Сценарии описываются кодом, поэтому живут в репозитории рядом с проектом и переживают смену команды.
Ключевое требование к инструменту — способность создать нужную нагрузку без искажений. Генератор, упирающийся в собственный процессор или сеть, покажет ограничение самого себя, а не системы. Поэтому нагрузку подают с отдельных машин, а перед серьёзным прогоном проверяют, что генератор не является узким местом.
Мониторинг во время теста важнее самого инструмента: без графиков со стороны системы вы получите только внешние цифры и никаких причин.
Как читать отчёт
Хороший отчёт отвечает не «выдержали или нет», а на четыре вопроса.
Какой запас есть сегодня. Целевой RPS профиля против фактически достигнутого до начала деградации.
Где узкое место. Конкретный компонент с доказательством: график пула соединений, топ тяжёлых запросов, время внешнего сервиса.
Как система ведёт себя за пределом. Плавная деградация с ростом времени ответа — приемлемо; каскадный отказ с потерей данных — критично.
Что делать. Список исправлений, отсортированный по соотношению эффекта и стоимости: обычно два-три изменения дают кратный прирост, а остальное — тонкая настройка.
Отдельно фиксируется, при каких условиях результат действителен: конфигурация стенда, объём данных, версия кода. Через полгода и три релиза цифры становятся историей, а не гарантией.
Если пик уже завтра
Ситуация, в которой к нам приходят чаще всего: распродажа послезавтра, а полноценный цикл занимает недели. Что можно успеть.
Снять самое тяжёлое. Найти пять самых медленных запросов по логам и закэшировать или упростить их. Обычно это карточка с рекомендациями, поиск с фильтрами и главная с подборками.
Отключить необязательное на время пика. Персональные блоки, тяжёлые счётчики, живой пересчёт остатков на каждый показ, рекомендации в реальном времени. Функциональность вернётся через два дня, выручка — нет.
Убрать фоновые процессы из окна пика. Ночные выгрузки, обмены с учётной системой, формирование отчётов, рассылки — всё, что можно передвинуть, двигается.
Поставить очередь и лимиты. Оформление заказа принимается в очередь и обрабатывается асинхронно, на входе — ограничение одновременных запросов, чтобы система деградировала предсказуемо, а не падала.
Договориться с внешними сервисами. Повышенные лимиты на период кампании запрашиваются заранее, а на случай отказа готовится запасной сценарий.
Подготовить план отката и дежурство. Кто смотрит графики, по какому признаку выключаем тяжёлые блоки, кого будим. Это дешевле любых доработок и спасает чаще всего.
Тест в конвейере
Разовый прогон перед распродажей — лучше, чем ничего, но производительность деградирует незаметно: каждый релиз добавляет по чуть-чуть.
Рабочая схема — два уровня. Короткий прогон в конвейере сборки на каждый релиз: один-два ключевых сценария, несколько минут, сравнение с прошлым результатом и предупреждение при ухудшении больше заданного порога. И полный прогон по расписанию — раз в квартал и перед сезоном.
Логика та же, что у регрессионного тестирования: важно не разовое подтверждение, а отсутствие ухудшений от релиза к релизу. Сценарии удобно строить на тех же пользовательских путях, что и сквозные тесты — маршрут уже описан, остаётся добавить нагрузку.
Сколько стоит
Объём работ определяют количество сценариев, состояние стенда и то, нужно ли потом исправлять найденное.
По нашим работам: аудит кода и архитектуры с разбором производительности — от 200 до 600 тыс. ₽, DevOps-работы отдельной услугой (стенд, мониторинг, конвейер) — от 200 тыс. ₽, доработка системы под нагрузку в составе проекта — от 1,7 млн ₽, разработка высоконагруженного продукта — от 5 млн ₽. Точная цифра зависит от сценариев и глубины разбора: оценка проекта бесплатная.
Прикинуть бюджет можно заранее — бесплатный калькулятор оценки собирает вилку по составу работ за несколько минут.
Ошибки
Тестируют не то. Сценарии придуманы, а не взяты из аналитики: нагружается страница, которую в пик почти не открывают.
Стенд не похож на прод. Другая конфигурация, пустая база, отключённые фоновые задания — результат не переносится.
Мониторинг не включили. Есть график времени ответа и ничего изнутри системы: узкое место остаётся гипотезой.
Нашли и не исправили. Отчёт лёг в папку, к распродаже готовились наймом людей на поддержку вместо двух правок в коде.
Проверили только идеальный путь. Реальный пик — это ещё и отвалившийся платёжный шлюз, и повторные попытки пользователей, и одновременная выгрузка в учётную систему.
С чего начать
Первое — достать цифры прошлого пика: максимум запросов в секунду, распределение по сценариям, что тогда сломалось. Если данных нет, начать нужно с мониторинга, а не с теста.
Второе — определить цель: какой трафик нужно выдержать и с каким временем ответа. Формулировка «должно работать быстро» не проверяется; «p95 не выше 500 мс при 300 запросах в секунду» проверяется.
Третье — оценить состояние стенда. Часто именно подготовка среды и обезличенных данных занимает больше времени, чем сам прогон, и это стоит знать заранее.
Часто задаваемые вопросы
Нагрузочное проверяет работу под ожидаемой нагрузкой заданное время: справляется ли система с плановым трафиком и с каким временем ответа. Стрессовое наращивает нагрузку до отказа, чтобы найти предел и увидеть характер поломки. Оба нужны: первое подтверждает готовность к плану, второе показывает запас прочности и то, восстановится ли система сама.
Иногда да, но с ограничениями: небольшая доля нагрузки, ночное окно, отдельные тестовые аккаунты, готовность мгновенно остановить прогон. Полноценный стресс-тест на боевой системе — способ устроить себе аварию. Практичнее собрать стенд, максимально похожий по конфигурации и объёму данных, и проверить на нём.
Универсальных нет, есть требования вашего продукта. Для интернет-магазина ориентир — время ответа основных страниц до полсекунды по p95 при пиковой нагрузке; для внутренней корпоративной системы допустимы секунды; для платёжной операции важнее стабильность, чем скорость. Числа фиксируются как требование до теста, иначе результат нечем оценивать.
Короткие прогоны ключевых сценариев — в конвейере на каждый релиз, чтобы ловить постепенную деградацию. Полный прогон — раз в квартал, перед сезонным пиком, перед крупной кампанией и после смены архитектуры или хостинга.
Аудит с разбором производительности — от 200 до 600 тыс. ₽, работы по стенду, мониторингу и конвейеру — от 200 тыс. ₽, доработки в составе проекта — от 1,7 млн ₽. Основная часть стоимости обычно приходится не на прогон, а на исправление найденного: запросы, кэш, очереди, вынос отчётности. Оценка бесплатная.
Разработка с Code Pilots
Code Pilots — студия заказной разработки полного цикла: веб- и мобильные продукты со сложной бизнес-логикой, интеграциями и высокими нагрузками. В подготовке к пикам мы делаем полный цикл: профиль нагрузки по вашим данным, сценарии, прогон с мониторингом изнутри системы, разбор узких мест и сами исправления — запросы, кэширование, очереди, вынос тяжёлой отчётности.
Границу обозначаем сразу: администрированием вашего серверного парка мы не занимаемся, аудит ведём по коду и архитектуре. Если проблема в инфраструктуре, скажем об этом прямо и покажем, где именно.
Внутри — backend-разработчики, DevOps, QA и аналитики, middle+ и senior. Пришлите цифры прошлого пика и дату следующего — этого достаточно, чтобы собрать профиль и оценить работу. Обсудить проект →