Gatling vs JMeter vs The Grinder: сравнение инструментов нагрузочного теста

1. Введение

Выбор правильного инструмента для работы может быть пугающим. В этом руководстве мы упростим это, сравнив три инструмента нагрузочного тестирования веб-приложений - Apache JMeter, Gatling и The Grinder - с простым REST API.

2. Инструменты тестирования нагрузки

Во-первых, давайте быстро рассмотрим некоторые из них.

2.1. Гатлинга

Gatling - инструмент для нагрузочного тестирования, который создает тестовые сценарии в Scala. Регистратор Гатлинга генерирует тестовые сценарии Scala, ключевую функцию для Гатлинга. Для получения дополнительной информации ознакомьтесь с нашим учебником Intro to Gatling .

2.2. JMeter

JMeter - это инструмент нагрузочного тестирования Apache. Он предоставляет приятный графический интерфейс, который мы можем использовать для конфигурации. Уникальная функция, называемая логическими контроллерами, дает большую гибкость при настройке тестов в графическом интерфейсе. **

Посетите наш учебник Intro to JMeter для получения снимков экрана и получения дополнительных пояснений.

2.3. Дробилка

И наш последний инструмент, The Grinder , предоставляет более мощный движок сценариев, чем два других, и использует Jython. Тем не менее, Grinder 3 имеет функциональность для записи сценариев.

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

3. Настройка тестового набора

Далее для нашего теста нам нужен API. Наша функциональность API включает в себя:

  • добавить/обновить запись вознаграждений

  • просмотреть одну/все награды

  • привязать транзакцию к записи о вознаграждениях клиентов

  • просмотр транзакций для записи вознаграждений клиентов

  • Наш сценарий: **

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

После этого мы запрашиваем транзакции.

3.1. Наш ОТДЫХ API

Давайте кратко рассмотрим API, просмотрев некоторые заглушки методов:

@PostMapping(path="/rewards/add")
public @ResponseBody RewardsAccount addRewardsAcount(@RequestBody RewardsAccount body)

@GetMapping(path="/rewards/find/{customerId}")
public @ResponseBody Optional<RewardsAccount> findCustomer(@PathVariable Integer customerId)

@PostMapping(path="/transactions/add")
public @ResponseBody Transaction addTransaction(@RequestBody Transaction transaction)

@GetMapping(path="/transactions/findAll/{rewardId}")
public @ResponseBody Iterable<Transaction> findTransactions(@PathVariable Integer rewardId)

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

  • К счастью, все наши инструменты справляются с этим довольно хорошо, некоторые лучше, чем другие. **

3.2. Наш план тестирования

Далее нам нужны тестовые скрипты.

Чтобы получить достоверное сравнение, мы выполним те же шаги автоматизации для каждого инструмента:

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

, Опубликовать транзакцию

, Разобрать ответ на случайный идентификатор клиента и идентификатор транзакции

, Запрос идентификатора учетной записи вознаграждения клиента с идентификатором клиента

, Разберите ответ по идентификатору учетной записи вознаграждений

, Если идентификатора учетной записи вознаграждений не существует, добавьте его с сообщением

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

номер транзакции , Запросить все транзакции по идентификатору учетной записи вознаграждений

Давайте подробнее рассмотрим шаг 4 для каждого инструмента. И не забудьте проверить The sample для всех трех завершенных сценариев .

3.3. Гатлинга

Для Гатлинга знакомство со Scala добавляет благ для разработчиков, поскольку API Гатлинга является надежным и содержит множество функций.

API Гатлинга использует подход DSL-компоновщика, как мы видим на шаге 4:

.exec(http("get__reward")
  .get("/rewards/find/${custId}")
  .check(jsonPath("$.id").saveAs("rwdId")))
.pause(1)

Особо следует отметить поддержку Gathling JSON Path, когда нам нужно прочитать и проверить ответ HTTP. Здесь мы подберем идентификатор награды и сохраним его во внутреннем состоянии Гатлинга. Обратите внимание на паузу в одну секунду, эта необходимая проверка предотвращает сбой следующего зависимого запроса. Вызов check и saveAs не блокировали последующие запросы exec .

Кроме того, язык выражений Гатлинга упрощает динамическое тело запроса Strings:

.body(StringBody(
  """{
    "customerRewardsId":"${rwdId}",
    "customerId":"${custId}",
    "transactionDate":"${txtDate}"
  }""")).asJson)

Наконец наша конфигурация для этого сравнения. 10 прогонов, заданных как повторение всего сценария, __atOnceUsers __method устанавливает потоки/пользователей:

val scn = scenario("RewardsScenario")
  .repeat(10) {
  ...
  }
  setUp(
    scn.inject(atOnceUsers(100))
  ).protocols(httpProtocol)
  • Https://github.com/eugenp/tutorials/tree/master/testing-modules/load-testing-comparison/src/main/resources/scripts[entire Scala скрипт]можно посмотреть в нашем репозитории Github. **

3.4. JMeter

  • JMeter генерирует файл XML после конфигурации графического интерфейса. ** Файл содержит специфические объекты JMeter с заданными свойствами и их значениями, например:

<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Add Transaction" enabled="true">
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="Transaction Id Extractor" enabled="true">

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

Наша конфигурация для прогонов и пользователей в JMeter использует ThreadGroups и LoopController :

<stringProp name="LoopController.loops">10</stringProp>
<stringProp name="ThreadGroup.num__threads">100</stringProp>

View весь файл jmx в качестве ссылки . Хотя это возможно, написание тестов в XML в виде файлов .jmx не имеет смысла с полнофункциональным графическим интерфейсом.

3.5. Дробилка

Без функционального программирования Scala и GUI наш Jython-скрипт для The Grinder выглядит довольно просто. Добавьте некоторые системные классы Java, и у нас будет намного меньше строк кода.

customerId = str(random.nextInt());
result = request1.POST("http://localhost:8080/transactions/add",
  "{"'"customerRewardsId"'":null,"'"customerId"'":"+ customerId + ","'"transactionDate"'":null}")
txnId = parseJsonString(result.getText(), "id")

Однако меньшее количество строк кода настройки теста уравновешивается необходимостью большего количества кода обслуживания строк, такого как анализ строк JSON. Кроме того, HTTPRequest API имеет небольшую функциональность.

С помощью Grinder мы определяем потоки, обрабатываем и запускаем значения во внешнем файле свойств:

grinder.threads = 100
grinder.processes = 1
grinder.runs = 10
  • Наш полный сценарий Jython для The Grinder будет выглядеть следующим образом: this .**

4. Тестовые прогоны

4.1. Выполнение теста

Все три инструмента рекомендуют использовать командную строку для тестов с большой нагрузкой.

Гатлинг требует только того, чтобы у нас были установлены JAVA HOME и GATLING HOME .

Для выполнения Гатлинга мы используем:

GATLING__HOME\bin\gatling.bat

JMeter нужен параметр, чтобы отключить графический интерфейс для теста, как было предложено при запуске графического интерфейса для конфигурации:

jmeter-n.cmd -t -l TestPlan.jmx -e -o[path to output folder]----

Как и Гатлинг, Grinder требует, чтобы мы установили __JAVA__HOME__ и __GRINDERPATH__. Тем не менее, ему нужно еще несколько свойств:

[source,powershell,gutter:,true]

set GRINDERPROPERTIES="%GRINDERPATH%\grinder.properties" set CLASSPATH="%GRINDERPATH%\lib\grinder.jar";%CLASSPATH%

Как упоминалось выше, мы предоставляем файл __grinder.properties__ для дополнительной настройки, такой как потоки, запуски, процессы и хосты консоли.

Наконец, мы загружаем консоль и агентов с помощью:

[source,powershell,gutter:,true]

java -classpath %CLASSPATH% net.grinder.Console

[source,powershell,gutter:,true]

java -classpath %CLASSPATH% net.grinder.Grinder %GRINDERPROPERTIES%

====  4.2. Результаты теста

Каждый из тестов проводился по десять прогонов с 100 пользователями/потоками. Давайте распакуем некоторые из основных моментов:

[cols=",^,^,^,^,^",]

| ================================================= ====================== | | **  Успешные запросы **  | **  Ошибки **  | **  Общее время тестирования (с) **  | **  Среднее время ответа (мс) **  | **  Пиковая пропускная способность **

| **  Gatling **  | 4100 запросов | 100 (soft) **  | 31 | 64,5 | 132 req/s

| **  JMeter **  | 4135 Запросов | 0 | 35 | 81 | 1080 req/s

| **  Grinder **  | 5000 запросов | 0 | 5.57 | 65.72 | 1284 req/s | =================================== =========================================

Взгляд показывает, что Grinder работает в 6 раз быстрее, чем два других инструмента для полного тестирования. Два других такта работали примерно через 30 секунд. Один и тот же шаг между The Grinder и Gatling, создав 100 потоков, занял 1544 мс и 16 мс соответственно.

И хотя Grinder высокоскоростен, он идет за счет дополнительного времени разработки и меньшего разнообразия выходных данных.

Дополнительное примечание У Гатлинга 100 «мягких» сбоев из-за логической проверки несуществующего идентификатора вознаграждения. Другие инструменты не считают условный сбой ошибкой. Это ограничение запечатлено в Gatling API.

[[test-summary]]

===  5. Резюме

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

[cols="^,^,^,^",]

| ==================================== | | **  Gatling **  | **  JMeter **  | **  The Grinder **  | Проект и сообщество | 9 | 9 | 6 | Производительность | 7 | 7 | 10 | Скриптистит/API | 7 | 9 | 8 | UI | 8 | 8 | 5 | Отчеты | 9 | 7 | 6 | Интеграция | 7 | 9 | 7 | **  Сводка **  | **  7,8 **  | **  8,2 **  | **  7 **  | ======================= ==================

**  Гатлинга: **

**  Твердый, отточенный инструмент для нагрузочного тестирования, который выводит красивые отчеты с

Scala скриптинг
**  Уровни поддержки Open Source и Enterprise для продукта

**  JMeter: **

**  Надежный API (через GUI) для разработки тестовых скриптов без программирования

требуется
**  Поддержка Apache Foundation и отличная интеграция с Maven

**  Мясорубка: **

**  Быстрый инструмент для нагрузочного тестирования производительности для разработчиков, использующих Jython

**  Межсерверная масштабируемость обеспечивает еще больший потенциал для больших тестов

Проще говоря, если скорость и масштабируемость необходимы, используйте Grinder.

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

JMeter - это инструмент для сложной бизнес-логики или уровня интеграции со многими типами сообщений. Как часть Apache Software Foundation, JMeter предоставляет зрелый продукт и большое сообщество.

===  6. Заключение

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

Наконец, API и скрипты можно найти https://github.com/eugenp/tutorials/tree/master/testing-modules/load-testing-comparison[on Github].