Нагрузочное тестирование это проверка того, как сайт, API или приложение ведут себя, когда ими одновременно пользуется много людей. Тест показывает, сколько запросов выдерживает система, где она начинает тормозить и что ломается первым: база данных, сервер приложения или внешний сервис оплаты.
Функциональное тестирование отвечает на вопрос "работает ли кнопка". Нагрузочное отвечает на другой: "будет ли она работать, когда ее одновременно нажмут тысячи человек". Ниже разбираем виды тестов, метрики, инструменты и несколько примеров, включая интернет-магазин перед распродажей.
Что такое нагрузочное тестирование приложения
Нагрузочное тестирование приложения это вид тестирования производительности, при котором на систему подают нагрузку, похожую на реальную, и замеряют скорость ответа, долю ошибок и потребление ресурсов. Нагрузку создают виртуальные пользователи: скрипты, которые повторяют действия пользователей с нужной частотой. Один генератор нагрузки способен изображать тысячи таких посетителей, а несколько генераторов вместе создают поток, который вручную не собрать никакой командой.
Проверять под нагрузкой имеет смысл любое программное обеспечение с сетевой частью: сайт, веб-приложение, бэкенд мобильного приложения, внутренний сервис с API. Зачем это нужно бизнесу:
- Узнать запас прочности до того, как придет рекламная кампания, сезон или черная пятница.
- Выявить узкие места: медленные запросы к базе данных, нехватку памяти, блокировки, лимиты внешних API.
- Понять, какое железо нужно, и не переплачивать за серверы, которые простаивают.
- Проверить, что обновление не ухудшило скорость. Новая функция может добавить тяжелый запрос, который незаметен, пока пользователь один.
От функционального тестирования нагрузочное отличается вопросом, на который отвечает. Функциональный тестировщик проверяет, что товар добавляется в корзину. Нагрузочный тест проверяет, что это происходит за приемлемое время, когда товары в корзину кладут сотни людей сразу. Оба вида нужны: система, которая быстро выдает ошибку, так же бесполезна, как система, которая правильно считает, но отвечает минуту. В плане проверок крупного проекта обычно три блока: функциональное тестирование, нагрузочное тестирование и проверка безопасности.
Результат теста описывает поведение системы под нагрузкой: при каком потоке запросов время ответа начинает расти, где появляются ошибки и какой ресурс заканчивается первым. Производительность системы в этих цифрах видна гораздо честнее, чем в ощущениях команды после ручной проверки.
Виды нагрузочного тестирования
Виды нагрузочного тестирования различаются целью и профилем нагрузки: сколько виртуальных пользователей подаем, как быстро их добавляем и сколько держим. Один и тот же сценарий, например оформление заказа, можно прогнать в каждом из режимов и получить разные ответы.
- Нагрузочный тест в узком смысле (load test). Подаем ожидаемую рабочую нагрузку и проверяем, что система держит ее с нужным временем ответа.
- Стресс-тест. Повышаем нагрузку сверх ожидаемой, пока система не начнет отказывать. Смотрим, где предел и как система восстанавливается после перегрузки.
- Тест стабильности (soak test). Держим обычную нагрузку много часов подряд. Так ловятся утечки памяти, переполнение диска логами, накопление открытых соединений к базе.
- Пиковый тест (spike test). Резко поднимаем нагрузку в несколько раз и так же резко снижаем. Так ведет себя трафик после рассылки или push-уведомления.
- Тест емкости (capacity test). Ищем максимальное количество пользователей или запросов, при котором система еще укладывается в требования.
- Тест объема (volume test). Проверяем работу на большом объеме данных: миллионы строк в таблицах, тяжелые отчеты, большие выгрузки.
На практике тесты комбинируют. Интернет-магазину перед распродажей обычно хватает нагрузочного, пикового и стресс-теста. Для сервиса, который работает круглосуточно, добавляем тест стабильности.
Отдельно делят тесты по объекту. Тест API проверяет сервер без интерфейса и дает самые точные цифры по времени ответа. Тест сайта через браузер ближе к поведению живого человека, но требует больше ресурсов на генерацию нагрузки. Для мобильного приложения нагружают его сервер: телефон тут не узкое место, а вот API, к которому одновременно обращаются тысячи установок, может не выдержать. Тест базы данных нужен, когда тормозят отчеты и выгрузки, а остальная система работает нормально.
Порядок обычно такой: сначала нагрузочный тест на ожидаемом трафике, потом стресс-тест, чтобы найти предел, и только затем длинный тест стабильности. Если первый тест провален, остальные запускать нет смысла: сначала исправляют то, что сломалось на обычной нагрузке.
Если нужно проверить ваш проект под ключ, от сценариев до отчета с узкими местами, посмотрите услугу нагрузочное тестирование сайта.
Какие метрики смотрят
- Время отклика: сколько миллисекунд проходит от запроса до ответа. Смотрим перцентили, а не среднее: p95 означает, что 95 процентов запросов уложились в это время. Среднее прячет медленные ответы, которые достаются каждому двадцатому пользователю.
- Пропускная способность: количество запросов в секунду (RPS), которое система обрабатывает без роста ошибок.
- Доля ошибок: ответы с кодами 5xx, таймауты, обрывы соединения.
- Ресурсы серверов: загрузка процессора, память, диск, сеть, число соединений к базе данных.
- Метрики базы: медленные запросы, блокировки, очередь на запись.
Метрики на стороне генератора нагрузки собирает сам инструмент теста. Метрики серверов снимает мониторинг, например Prometheus с дашбордами в Grafana. Без второй половины картины видно, что система тормозит, но непонятно, почему.
Как сделать нагрузочное тестирование?
Проведение нагрузочного тестирования мы делим на семь шагов.
- Цели и требования. Договариваемся, какую нагрузку система должна выдержать и с каким временем ответа. Источники цифр: аналитика посещаемости, планы маркетинга, пиковые дни прошлого года. Без цели тест превращается в измерение ради измерения.
- Профиль нагрузки. Описываем, что делают пользователи и в какой пропорции: сколько смотрят каталог, сколько ищут, сколько оформляют заказ. Профиль нужно максимально приблизить к реальному поведению, иначе тест нагрузит не те части системы.
- Стенд. Тестируем на копии рабочего окружения с сопоставимым железом и объемом данных. Тест на ноутбуке разработчика или на пустой базе дает красивые и бесполезные цифры.
- Скрипты. Пишем сценарии в инструменте: запросы, паузы между действиями, тестовые данные, проверки ответов.
- Прогоны. Начинаем с малой нагрузки, чтобы проверить сами скрипты, затем ступенями поднимаем до целевой и выше. Перед проведением теста предупреждаем владельцев внешних сервисов, чтобы нагрузку не приняли за атаку.
- Анализ результатов. Сопоставляем графики нагрузки, времени ответа и ресурсов, находим момент деградации и его причину.
- Исправления и повтор. Разработчики чинят узкое место, тест повторяется. Часто после первого исправления проявляется следующее ограничение, и цикл идет еще раз.
Проводить нагрузочное тестирование стоит регулярно: после крупных релизов и перед каждым ожидаемым пиком, а не один раз перед запуском. Когда проект прошел нагрузочное тестирование, нагрузочные скрипты сохраняем в репозитории рядом с кодом. Короткий тест удобно встроить в CI (автоматическую сборку и проверку кода), чтобы падение скорости всплывало сразу после изменений.
Инструменты: Apache JMeter, k6 и другие
- Apache JMeter. Проверенный инструмент на Java с графическим интерфейсом. Поддерживает HTTP, JDBC, JMS и много других протоколов, у него большая библиотека плагинов. Минус: требует много ресурсов, а сценарии хранятся в XML и плохо читаются при ревью кода.
- k6. Сценарии пишутся на JavaScript, инструмент легкий и удобно встраивается в CI. Хорошо подходит для API и веб-сервисов.
- Gatling. Сценарии на Scala, Java или Kotlin, подробные HTML-отчеты без дополнительной настройки.
- Locust. Сценарии на Python, удобно, если команда и так пишет на этом языке.
Для мобильных приложений нагружают сервер приложения и API, к которым обращаются клиенты, а не сам телефон. Поэтому инструменты те же, а скрипты повторяют запросы, которые отправляет приложение. Скорость и стабильность самого клиента на устройстве проверяют отдельно, в функциональных и UI-тестах.
Как читать отчет
Результат нагрузочного тестирования приходит в виде графиков и таблицы по каждому запросу. Читаем их в таком порядке:
- Находим точку, где время ответа начинает расти быстрее нагрузки. Это предел текущей конфигурации.
- Смотрим, что в этот момент происходит с ресурсами: уперлись в процессор, память, диск или число соединений.
- Проверяем ошибки: появились ли таймауты и 5xx, на каких запросах.
- Сравниваем с требованиями: укладывается ли p95 в договоренный порог на целевой нагрузке.
- Сравниваем с прошлым прогоном, чтобы увидеть, стало лучше или хуже.
Хороший отчет заканчивается списком узких мест с приоритетами и рекомендациями: добавить индекс, включить кэш, вынести отправку писем в очередь, увеличить пул соединений. Цифры без выводов заказчику не помогут.
Частые ошибки при проведении нагрузочного тестирования
Неверные выводы чаще всего получаются из-за подготовки теста. Вот что мы проверяем до первого прогона.
- Один сценарий на всех. Если все виртуальные пользователи открывают главную страницу, тест покажет прекрасные цифры: главная обычно лежит в кэше. Реальные покупатели ищут, фильтруют и оформляют заказы, и нагрузка ложится на другие части системы.
- Одни и те же тестовые данные. Когда тысяча скриптов запрашивает один товар, ответ приходит из кэша. Для честного результата в скрипты подставляют разные товары, поисковые фразы и учетные записи.
- Нет пауз между действиями. Живой человек читает страницу несколько секунд, скрипт без пауз шлет запросы непрерывно. Такой тест создает нагрузку, которой в жизни не бывает, и путает выводы.
- Генератор нагрузки сам стал узким местом. Если машине, с которой идет тест, не хватает процессора или сети, в отчете растет время ответа, хотя сервер справляется. Ресурсы генератора мониторим так же, как ресурсы серверов.
- Тест на рабочем окружении без согласования. Нагрузка на живой сайт в разгар дня может уронить его для настоящих клиентов. Если стенда нет, прогоны проводим ночью и по согласованию с командой эксплуатации.
Каждый пункт отнимает немного времени на старте и избавляет от повторных прогонов.
Нагрузочное тестирование: примеры
Первый пример: API мобильного приложения. Допустим, приложение рассылает push-уведомление об акции, и заметная часть аудитории открывает его почти одновременно. Каждый запуск отправляет несколько запросов: авторизация, профиль, лента акций. Пиковый тест показывает, что сервер отвечает, а база данных не успевает: запрос ленты перебирает таблицу целиком. После добавления индекса и кэширования ленты тот же пик проходит без ошибок.
Второй пример: внутренний сервис с отчетами. Днем нагрузка небольшая, но в конце месяца бухгалтерия запускает тяжелые выгрузки. Тест объема на копии рабочей базы выявляет, что формирование отчета блокирует таблицы, и остальные пользователи ждут. Решение: перенести отчеты на реплику базы и формировать их в фоне.
Третий пример: сайт после редизайна. Функционально все работает, но новая главная страница делает десятки запросов к серверу вместо нескольких. Нагрузочный тест с тем же профилем, что и до редизайна, показывает рост времени ответа, и команда исправляет это до релиза, а не после жалоб.
Если вы знаете, что нагрузка будет расти, архитектуру под нее лучше закладывать с первого дня. Этим занимается разработка высоконагруженных систем: мы проектируем масштабирование, кэши и очереди, а нагрузочные тесты подтверждают, что расчеты верны.
Нагрузочное тестирование сайта: пример
Разберем пример нагрузочного тестирования сайта. Условный интернет-магазин готовится к черной пятнице. В обычные дни сайт работает быстро, но на прошлой распродаже страницы открывались медленно, а часть заказов не оформилась.
Шаг 1. Требования. Из аналитики берем пиковую посещаемость прошлой распродажи и умножаем на прогноз маркетинга. Договариваемся о пороге: главная и каталог отвечают за доли секунды, оформление заказа укладывается в пару секунд на 95 процентах запросов.
Шаг 2. Профиль. Действия пользователей раскладываем по долям: большинство смотрит главную и каталог, часть пользуется поиском, меньшая часть кладет товар в корзину, и совсем немногие доходят до оплаты. Сценарий "товар в корзину, корзина, оформление заказа" нагружает самые тяжелые части магазина: расчет доставки, резерв остатков, платежный шлюз.
Шаг 3. Стенд и данные. Разворачиваем копию магазина с реальным каталогом. Платежный шлюз и службу доставки подменяем заглушками (имитацией внешнего сервиса с тем же временем ответа), чтобы не создавать настоящие платежи.
Шаг 4. Прогоны. Поднимаем число виртуальных пользователей ступенями и следим за количеством запросов в секунду, временем ответа и ошибками. На определенном уровне нагрузки время оформления заказа резко растет, хотя каталог отвечает нормально.
Шаг 5. Поиск причины. Мониторинг показывает, что веб-сервер и сервер приложения загружены умеренно, а база данных упирается в блокировки: при каждом заказе пересчитываются остатки по всему складу. Разработчики переносят резерв остатков в отдельную быструю операцию, и повторный тест подтверждает, что порог выдержан с запасом.
Шаг 6. Пиковый тест. Имитируем старт распродажи, когда покупатели приходят по рассылке в одну и ту же минуту. Выясняется, что поиску нужен кэш популярных запросов. После этого исправления магазин готов к распродаже, а скрипты остаются в репозитории до следующего сезона.
Такой же подход работает для любого веб-приложения: меняются сценарии, логика проверки остается. Функциональные проверки перед распродажей тоже никто не отменял. Если нужен полный цикл, от функциональных тестов до нагрузочных, посмотрите нашу услугу тестирование мобильных приложений и сайтов. Примерный бюджет проекта можно прикинуть в калькуляторе.
Услуга студии
Нагрузочное тестирование сайтов и приложений
Нагрузочное тестирование сайта, API и сервера приложения: проверяем, сколько пользователей выдержит система, находим узкие места и даем план исправлений.