Основы нагрузочного тестирования ПО

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

1. Введение в нагрузочное тестирование: цели, виды и основные понятия

Введение в нагрузочное тестирование: цели, виды и основные понятия

Добро пожаловать на курс «Основы нагрузочного тестирования ПО». Это первая статья, в которой мы заложим фундамент для всех последующих занятий. Мы разберемся, зачем ломать приложения большим количеством запросов, какие метрики действительно важны и чем стресс-тестирование отличается от тестирования стабильности.

Что такое нагрузочное тестирование?

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

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

Нагрузочное тестирование (Performance Testing) — это вид нефункционального тестирования, который проводится для определения производительности системы под определенной нагрузкой.

!Схема процесса: генераторы нагрузки отправляют запросы к системе для проверки её поведения.

Зачем это нужно?

Главная цель — не просто «уронить» сервер (хотя это тоже бывает весело), а получить ответы на конкретные вопросы:

* Скорость: Отвечает ли система достаточно быстро? * Масштабируемость: Сможет ли система обработать в 10 раз больше пользователей, если мы добавим в 10 раз больше серверов? * Стабильность: Не упадет ли приложение через 24 часа непрерывной работы? * Надежность: Что произойдет при ошибке в базе данных или отказе одного из узлов?

Основные понятия и метрики

Чтобы говорить о производительности, нам нужен общий язык. В нагрузочном тестировании всё опирается на цифры. Давайте разберем ключевые метрики.

1. RPS (Requests Per Second)

Это количество запросов, которое система обрабатывает в секунду. Это основной показатель интенсивности нагрузки.

Формула расчета проста:

Где — количество запросов в секунду, — общее количество отправленных запросов, а — время в секундах, за которое эти запросы были отправлены.

Иногда используется термин TPS (Transactions Per Second). Разница в том, что транзакция может состоять из нескольких запросов (например, «положить товар в корзину» — это одна бизнес-транзакция, но технически она может включать запросы к базе данных, сервису склада и сервису рекомендаций).

2. Время отклика (Response Time / Latency)

Это время, прошедшее с момента отправки запроса до получения ответа. Казалось бы, всё просто: чем меньше, тем лучше. Но здесь кроется главная ловушка новичков — использование среднего арифметического.

> Среднее время отклика — это «средняя температура по больнице». Оно скрывает проблемы.

Если 99 пользователей получили ответ за 1 секунду, а один пользователь — за 100 секунд, среднее будет приемлемым, но один клиент уйдет в ярости.

3. Перцентили (Percentiles)

Для объективной оценки времени отклика используют перцентили. Это понятие из математической статистики.

Обозначается как (или -й перцентиль). Например, (95-й перцентиль).

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

Где — значение -го перцентиля, — функция получения значения из выборки по индексу, — процент (например, 90 или 99), а — общее количество измерений.

Простыми словами: Если мс, это значит, что 95% всех запросов выполнились быстрее или ровно за 200 миллисекунд, и только 5% пользователей ждали дольше. Это гораздо честнее, чем среднее значение.

4. Виртуальные пользователи (Virtual Users / VUsers)

Это потоки, которые эмулируют поведение реальных людей. Важно понимать разницу между RPS и виртуальными пользователями. 100 пользователей могут генерировать 1000 RPS (если они очень активны) или всего 10 RPS (если они «думают» перед каждым кликом).

Виды нагрузочного тестирования

Не вся нагрузка одинакова. В зависимости от целей, мы выбираем разные профили подачи нагрузки.

!Графическое представление профилей нагрузки для разных видов тестирования.

1. Тестирование производительности (Load Testing)

Это «обычное» нагрузочное тестирование. Мы подаем ожидаемую нагрузку (например, ту, которая планируется в продакшене) и проверяем, справляется ли система.

* Цель: Убедиться, что система соответствует требованиям (SLA). * Вопрос: «Выдержим ли мы 1000 пользователей с откликом не более 2 секунд?»

2. Стресс-тестирование (Stress Testing)

Здесь мы намеренно ищем предел прочности. Мы увеличиваем нагрузку до тех пор, пока система не сломается.

* Цель: Найти точку отказа (bottleneck) и проверить восстанавливаемость системы после сбоя. * Вопрос: «При какой нагрузке сервер упадет? И поднимется ли он сам, когда нагрузка спадет?»

3. Тестирование стабильности (Stability / Soak Testing)

Длительное тестирование под средней нагрузкой. Оно может длиться часы или даже дни.

* Цель: Найти утечки памяти (memory leaks), проблемы с переполнением диска или логов. * Вопрос: «Не деградирует ли производительность системы через 24 часа работы?»

4. Пиковое тестирование (Spike Testing)

Резкое увеличение нагрузки за короткое время и такой же резкий спад. Эмуляция ситуаций вроде «Черной пятницы» или выхода новой серии популярного сериала.

* Цель: Проверить, как система реагирует на резкие скачки и успевает ли масштабироваться (Auto-scaling).

5. Тестирование масштабируемости (Scalability Testing)

Проверка способности системы увеличивать производительность при добавлении ресурсов.

Формально эффективность масштабирования можно оценить так:

Где — эффективность, — производительность (например, в RPS), а — количество ресурсов (например, CPU или количество серверов). Индексы 1 и 2 обозначают состояния до и после масштабирования.

Инструменты

В этом курсе мы не будем привязываться к одному инструменту, но вам стоит знать основных игроков на рынке:

  • Apache JMeter: Классика. Мощный, бесплатный, но с интерфейсом из прошлого и высоким порогом вхождения.
  • Gatling: Код как тест (Scala/Java/Kotlin). Очень производительный.
  • k6: Современный инструмент от Grafana Labs. Сценарии пишутся на JavaScript. Легкий и быстрый.
  • Locust: Сценарии на Python. Прост в освоении, но менее производителен, чем аналоги на Go или Java.
  • Заключение

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

    Помните: > «Преждевременная оптимизация — корень всех зол». > — Дональд Кнут

    Но отсутствие тестирования перед релизом — это корень ночных звонков от разгневанного заказчика.

    2. Планирование тестирования: профиль нагрузки, метрики и сценарии использования

    Планирование тестирования: профиль нагрузки, метрики и сценарии использования

    В предыдущей статье мы разобрались, что такое нагрузочное тестирование и зачем оно нужно. Теперь, когда мы знаем «зачем», пришло время понять «как». Многие новички совершают одну и ту же ошибку: они сразу открывают JMeter или k6 и начинают писать скрипты. Это путь в никуда.

    Успешное нагрузочное тестирование на 80% состоит из планирования и анализа, и только на 20% — из написания кода и запуска тестов. Сегодня мы научимся составлять профиль нагрузки, определять правильные метрики и проектировать реалистичные сценарии.

    Сбор требований: чего мы хотим добиться?

    Прежде чем нагружать систему, нужно понять, что считается «хорошим» результатом. Для этого в инженерии используются три аббревиатуры, которые часто путают: SLA, SLO и SLI.

    SLI, SLO и SLA: в чем разница?

    Представьте, что вы заказываете пиццу. Пиццерия обещает доставить её за 30 минут.

  • SLI (Service Level Indicator) — это фактическое измерение. Курьер приехал за 28 минут. Ваш SLI = 28 минут.
  • SLO (Service Level Objective) — это цель, к которой мы стремимся. Пиццерия хочет доставлять 95% заказов быстрее 30 минут. Это внутренняя цель команды.
  • SLA (Service Level Agreement) — это контракт с пользователем. Если курьер не приедет за 40 минут, вы получите пиццу бесплатно. Это внешнее обязательство с штрафными санкциями.
  • В нагрузочном тестировании мы чаще всего работаем с SLO. Нам нужно проверить, соответствуют ли показатели системы нашим внутренним целям.

    Типичные требования выглядят так: * Время отклика (Response Time) 95-го перцентиля < 2 секунд. * Процент ошибок (Error Rate) < 0.1%. * Пропускная способность (Throughput) >= 1000 RPS.

    Профиль нагрузки: математика реальности

    Профиль нагрузки — это модель того, как пользователи работают с вашей системой. Если вы подадите нагрузку неправильно, результаты теста будут бесполезны.

    Как рассчитать целевой RPS?

    Часто бизнес приходит с задачей: «У нас будет 100 000 пользователей в день. Протестируй». Но 100 000 пользователей в день — это не нагрузка в секунду. Нам нужно перевести бизнес-метрики в технические.

    Базовая формула для расчета среднего RPS выглядит так:

    Где: * — среднее количество запросов в секунду. * (Daily Active Users) — количество уникальных пользователей в сутки. * — среднее количество запросов, которое делает один пользователь за сеанс. * — количество секунд в рабочем дне (обычно берут 12 или 24 часа, переведенные в секунды, то есть или ).

    Пример: У нас интернет-магазин. Ожидаем 50 000 посетителей в сутки (). В среднем пользователь просматривает 10 страниц, каждая страница делает 3 API-запроса. Итого 30 запросов на пользователя (). Магазин работает круглосуточно ().

    Получается всего около 17 запросов в секунду. Кажется, мало? Да, потому что это средняя нагрузка, размазанная ровным слоем по суткам. Но люди спят ночью и активны вечером.

    Учет пиковой нагрузки

    Чтобы тест был реалистичным, нам нужно найти пиковую нагрузку. Для этого вводится коэффициент неравномерности (). Обычно он составляет от 2 до 5, в зависимости от характера бизнеса (для службы доставки еды в обед он может быть и 10).

    Где: * — пиковая нагрузка в секунду. * — средняя нагрузка, рассчитанная ранее. * — коэффициент пиковой нагрузки.

    Если мы возьмем , то для нашего магазина:

    Теперь мы знаем, что наша система должна держать минимум 52 RPS. Это и есть наша цель для теста производительности.

    !Суточный профиль нагрузки: разница между средним и пиковым значением может быть многократной.

    Модель закрытой и открытой нагрузки

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

    Закрытая модель (Closed Workload)

    В этой модели у вас фиксированное количество пользователей. Новый пользователь заходит в систему только тогда, когда старый вышел (или закончил действие). Это похоже на турникет в метро: пока один не пройдет, второй ждет.

    * Контролируемый параметр: Количество виртуальных пользователей (VUsers). * Где применяется: Корпоративные системы, где число сотрудников фиксировано (например, CRM для колл-центра).

    Открытая модель (Open Workload)

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

    * Контролируемый параметр: Интенсивность прибытия (RPS / Arrival Rate). * Где применяется: Публичные веб-сайты, «Черная пятница», DDoS-атаки.

    > Выбор неправильной модели может дать ложное чувство безопасности. Если вы тестируете публичный сайт закрытой моделью, вы не увидите, как очередь запросов убивает базу данных.

    Сценарии использования (User Scenarios)

    Мы посчитали цифры, теперь нужно понять, что именно делают пользователи. Нельзя просто «бомбить» главную страницу.

    Принцип Парето в тестировании

    Обычно 20% функционала создают 80% нагрузки. Нам не нужно писать скрипты для смены пароля или редактирования профиля, если это делают раз в год. Нам нужны критические пути.

    Типичный сценарий для E-commerce:

  • Открыть главную.
  • Поиск товара.
  • Открыть карточку товара.
  • Добавить в корзину.
  • Оформить заказ (Checkout).
  • Весовые коэффициенты

    Не все пользователи доходят до конца. На 100 просмотров главной страницы может приходиться только 1 покупка. Это нужно отразить в профиле.

    Пример распределения интенсивности: * Главная страница: 100% потоков. * Поиск: 60% потоков. * Корзина: 10% потоков. * Покупка: 2% потоков.

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

    Подготовка данных (Test Data)

    Одна из самых больших болей нагрузочного тестирования — данные.

    Проблема кэширования

    Если вы будете запрашивать один и тот же товар (product_id=100) 1000 раз в секунду, база данных просто закэширует этот ответ. В реальности пользователи смотрят разные товары. Тест покажет отличную производительность, а в продакшене все упадет, потому что кэш не спасет от разнообразия запросов.

    Правило: Используйте CSV-файлы с тысячами различных ID, логинов и поисковых запросов. Данные должны быть максимально рандомизированы (Parametrization).

    Изоляция данных

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

    Think Time (Время на раздумья)

    Реальный пользователь не кликает со скоростью пулемета. Он открывает страницу, читает, скроллит, думает. Это называется Think Time.

    Если вы не добавите задержки (паузы) между запросами в скрипте, 100 виртуальных пользователей создадут нагрузку, как 10 000 реальных. Это приведет к нереалистичным результатам.

    Чек-лист готовности к тестированию

    Перед тем как переходить к написанию скриптов (чем мы займемся в следующей статье), проверьте себя по этому списку:

  • Цели ясны: Мы знаем ожидаемый RPS и максимальное время отклика.
  • Профиль составлен: Мы знаем соотношение операций (сколько поисков, сколько покупок).
  • Среда готова: Тестовый стенд изолирован от разработки и похож на продакшен (или мы знаем коэффициент масштабирования).
  • Данные подготовлены: Есть база с достаточным количеством товаров/пользователей, чтобы избежать эффекта кэширования.
  • Мониторинг настроен: Мы видим загрузку CPU, памяти и диска на серверах во время теста.
  • Планирование — это карта. Без неё вы просто блуждаете в лесу метрик и логов. В следующий раз мы возьмем в руки компас — инструмент Apache JMeter — и сделаем первый шаг по этой карте.