Gatling

В чём сильные стороны Gatling и когда его выбирают для более сложных и масштабных performance-сценариев.

Обновлено:

Содержание

Gatling — инструмент для нагрузочных сценариев, которые удобно поддерживать как код: обсуждать изменения, хранить историю и повторять испытания с известной конфигурацией. Он помогает моделировать потоки операций и измерять их результат. В этой статье используется Java SDK для HTTP; возможности других SDK и режимов проверяют по документации выбранной версии.

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

Когда полезен такой подход

Предположим, команда развивает API с каталогом и оформлением заказа. Сценарий меняется вместе с контрактом, а сравнение версий необходимо регулярно. Код позволяет проверить логику нагрузки на review и сохранить точную версию рядом с результатами.

Это не отменяет затрат на поддержку. Кто-то должен понимать SDK, формат данных и устройство приложения. Выбор инструмента оправдан, когда команда готова поддерживать сценарий после первого запуска. Однократная запись и забытый отчёт не создают устойчивого процесса проверки производительности.

Структура симуляции

Simulation объединяет настройки протокола, сценарии, профиль запуска и итоговые assertions. Сценарий описывает последовательность действий. Session хранит данные конкретного виртуального пользователя; checks извлекают или проверяют значения ответов. Общие изменяемые переменные вне Session могут случайно смешать данные пользователей.

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

Минимальный сценарий Java

Код ниже помещают в CatalogSimulation.java внутри настроенного Maven-проекта Gatling Java. На собственном стенде /api/catalog возвращает JSON с массивом items. Порог в 500 мс — учебный; команда заменяет его согласованным критерием.

java
import io.gatling.javaapi.core.Simulation;
import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;

public class CatalogSimulation extends Simulation {
  {
    var protocol = http.baseUrl(
        System.getProperty("baseUrl", "https://qa.example.test"));
    var catalog = scenario("Catalog reads")
        .exec(http("catalog")
            .get("/api/catalog")
            .check(status().is(200), jsonPath("$.items").exists()));

    setUp(catalog.injectOpen(constantUsersPerSec(5).during(60)))
        .protocols(protocol)
        .assertions(
            global().failedRequests().percent().lt(1.0),
            global().responseTime().percentile(95.0).lt(500));
  }
}
shell
mvn gatling:test -Dgatling.simulationClass=CatalogSimulation -DbaseUrl=https://qa.example.test

В проекте должны быть согласованные зависимости SDK и Maven plugin. Пример использует класс без package; при добавлении package параметр simulationClass меняют на полное имя класса. Сначала выполните одиночный smoke-прогон, затем заданную нагрузку.

Открытая и закрытая модель

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

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

Feeders и тестовые данные

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

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

Корреляция и проверки

После создания корзины извлеките её идентификатор в Session, затем подставьте в запрос добавления товара. Проверяйте успешное извлечение и прекращайте бессмысленную цепочку при критической ошибке. Иначе последующие отказы заполнят отчёт и скроют исходную причину.

В минимальном примере проверка существования items подтверждает только наличие узла. Для реального каталога добавьте проверку типа и существенных бизнес-значений. Для оформления заказа подтвердите итоговую сумму и состояние объекта через контракт. Assertions по задержкам не компенсируют слабую проверку корректности ответа.

Паузы и время операции

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

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

Мониторинг и доказательства

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

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

Ошибки и интерпретация результата

Частые ошибки — путать arrival rate с concurrency, использовать один токен на всех, считать любой JSON успехом и ориентироваться только на общий percentile. Короткий запуск также не подтверждает устойчивость при длительной работе и не обнаруживает все эффекты накопления данных.

Для приведённого сценария полезный вывод звучит конкретно: чтение каталога выполнило выбранные пороги при указанной частоте начала операций и конфигурации стенда. Нарушение порога требует анализа ошибок и ресурсов. Gatling помогает сделать такой вывод повторяемым, но не выбирает бизнес-критерии вместо команды.

Что ещё почитать