Performance of Performance Testing tools

💡 Усі статті, обговорення, новини про тестування — в одному місці. Приєднуйтесь до QA спільноти!

Минулого року я брав участь в конференції QA Fest 2019 та презентував свої дослідження з порівняння додатків для тестування навантаження. Моєю метою було підготувати середовище та виконати однакові набори тестів для Locust, Gatling та JMeter, порівняти, наскільки релевантні їх результати та скільки ресурсів їм треба для роботи. Хто хоче, може подивитись відео доповіді:

Чому я вибрав саме ці 3 тули проміж десятків інших? Мої основні критерії:

  • Є безкоштовним
  • Має велику спільноту і нормальну документацію
  • Може генерувати навантаження в 10 000 користувачів
  • Підтримує без болі та страждань транзакційність (дані з одного респонсу веб серверу можуть бути використані в наступному реквесті)

Тож я провів тести, записав результати і презентував їх. Але сам лишився не дуже задоволений проведеною роботою — JMeter згенерував безліч помилок в процесі роботи, результати тестів для всіх тулів відрізнялись і взагалі — майже за рік оновились версії ОС та фреймворків — чому б не провести роботу над помилками тести ще кілька разів?

Мета

Я хочу провести однакові тести навантаження одного й того самого серверу в одних і тих самих умовах і перевірити, наскільки будуть відрізнятись результати тесту та ресурси, що потрібні тулам для роботи. Щоб при нагоді точно розуміти, чим можна користуватись, які можуть будти підводні камені та чиїм результатам можна довіряти.

Setup

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

Locust

Власне, нічого дуже складного у встановленні немає — інструкція є в офіційній документації Locust: Треба мати Python version 3.6+ і виконати наступну команду в консолі:
pip install locust
Але виявилось, у Windows 10 та з python 3.8 не все так просто. Якщо спробувати встановити, вам буде показано помилку і пропозицію встановити MS C++ в пакеті Visual Studio Build Tools (виявляється, деякі модулі Locust написані на C++ та компілюються на вашому ПК для пришвидшення швидкодії). Записав окреме відео про це

Gatling

Передумовами для встановлення є:
  • Java 8+
  • Scala 2.12 (саме така версія)
  • Apache Maven (опціонально)
  • Gatling binaries
Насправді, навіть IDE не потрібна — тести можна писати навіть в блокноті і потім копіювати в папку з файлами Gatling.
Але мені більше подобається, коли є підсвітка синтаксису, підказки та автодоповнення коду. Тому вирішив написати гайд, як запускати тести в IntelliJ IDEA:

JMeter

Певне, найпопулярніша програма для тестування навантаження. Не має ніяких підводних каменів. Треба мати Java 8+ та, власне, завантажити JMeter. І можна користуватись.

Що тестувати?

В якості «жертви» я вирішив написати малий веб сервер з усього одним REST endpoint’ом — який буде повертати строку hello world на GET запит. Веб сервер розгорнув в докері на домашньому NAS. Сам сервер написав (якщо так можна сказати) на python, використовуючи фреймворк Flask. Розгорнув сервер за допомоги Gunicorn + nginx.

Весь код сервера:

from flask import Flask, escape, request, send_file

app = Flask(__name__)

@app.route('/')
def hello():
    name = request.args.get("name", "World")
    return f'Hello, {escape(name)}!'

@app.route('/access.log')
def access_log():
    return send_file('access.log', cache_timeout=-1)

Уважні читачі можуть помітити, що в коді 2 ендпоінта — другий я додав, щоб виводити access.log і перевіряти, чи справді всі мої запити досягли серверу.

Докер файл:

FROM python:3.7-alpine
COPY perf_target.py /app/perf_target.py
WORKDIR /app
RUN pip install --upgrade pip && pip install flask gunicorn
EXPOSE 8888
CMD gunicorn -w 4 -b 0.0.0.0:8888 --access-logfile access.log perf_target:app

Test Configuration

Найменш гнучка частина моїх тестів — конфігурація системи, на якій я буду генерувати навантаження. Але від неї залежить якість моїх тестів та релевантність результатів (крім того, як я вже писав раніше, я оновив «залізо», ОС та всі програми до останніх версій і можу додатково порівняти, як сильно це вплинуло).
Test PC:
  • CPU AMD Ryzen 7 4800H 2.9 Ghz
  • RAM 16 Gb
  • Windows 10 2004 Pro x64
  • Java 8
  • Scala 2.12
  • Python 3.8
Target server (NAS):
  • CPU Intel Celeron J1900 2 Ghz
  • RAM 8 Gb
  • Flask WS in Docker python:3.7-alpine 4 Gb RAM
Network connection:
  • 100 Mbps (за найповільнішою ланкою в моїй домашній мережі)

Додаткова передумова, до якої я прийшов пізніше, і яка змусила мене переробити тести — додати значення в реєстр Windows, що дозволяє ОС збільшити ліміт мережевих підключень. Без нього «важкі» тести ламаються через неможливість створити мережеве з’єднання:

Name: MaxUserPort
Type: DWORD 
Value: 65534 decimal
Path: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

Тестові сценарії

Ідея тестів проста — навантаження лінійно зростає протягом Ramp time, потім тест має видавати однакове навантаження, протягом якого треба зібрати метрики серверу (throughput, середній та медіанний час відповіді) та клієнту (CPU, RAM, threads).
Також вирішив записати проходження всіх тестів, щоб потім можна було проаналізувати їх перебіг та результати.

Код тестів

Locust
from locust import HttpUser, task, between


class WebsiteUser(HttpUser):
   host = 'http://192.168.2.136:8888/'
   wait_time = between(1, 2)

   @task
   def posts(self):
       self.client.get("/")
Gatling
package Sample

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._


class MaxPerformance extends Simulation {

  val httpProtocol = http
    .baseUrl("http://nas:8888")

  val scn = scenario("max performance")
    .forever(exec(http("simple get")
      .get("/"))
      .pause(1 second, 2 seconds))

  setUp(scn.inject(rampUsers(10000) during (20 seconds), nothingFor(2 minutes)))
    .pauses(normalPausesWithStdDevDuration(2 seconds))
    .maxDuration(180 seconds).protocols(httpProtocol)
}

JMeter

І щоб уникнути непорозумінь — запускав тест я з консолі, як радить офіційна документація:

jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]

Test #1

Моя початкова ідея — виконати «важкий тест», що зможе нагрузити як сервер, так і систему, на якій я виконую тест. Обрав наступні параметри:
  • 10 000 users
  • 1 GET request
  • Expected result — HTTP 200 OK
  • пауза між викликами 1-2 sec
  • Ramp time — 20 sec — лінійне зростання навантаження
  • Час тесту — 3 min

Тести проведено, метрики зібрано:

Metric Locust JMeter Gatling
Throughput (RPS)533475794
Average response time, sec10.515.69.8
Median response time, sec132110
Test PC RAM, Gb0.82.31.5
Test PC Threads1410056117
Total requests114 882100 797142 997
Success rate, %1003629

Які висновки та нотатки я зробив:

  1. Без зміни в реєстрі Windows всі 3 тести мають невеликий Success rate — тобто багато запитів навіть не були створені і не змогли навантажити сервер
  2. Заміри CPU клієнта більше плутають. Я вимірював їх за допомоги тулів perfmon та procexp. Перший показував завантаження 100%, другий — до 10%. В Інтернеті кажуть, що різниця може бути в методі підрахунку (враховуючи system idle чи ні) та кількості ядер. Якщо хтось знає, в чому причина — напишіть, думаю, багатьом цікаво!
  3. Якщо ви шукаєте в таблиці метрики CPU та RAM сервера — їх там немає, оскільки моя мета була протестувати тули, а не сервер — я нехтую цими метриками
  4. Locust повільніше за всіх створює 10 000 користувачів. Я встановив швидкість у 500 користувачів на секунду, але знадобилась приблизно хвилина, щоб створити всіх
  5. При цьому Locust потребує найменше ресурсів та не має жодної помилки — на всі 114 з гаком тисяч запитів отримав HTTP 200 OK
  6. В тестах JMeter та Gatling майже всі помилки — request timeout
  7. JMeter має найпростішу реалізацію, у порівнянні з іншими (шо потребує значних ресурсів) — як бачите, 10 000 користувачів — 10 000 паралельних потоків
  8. Чисто з цікавості запускав тест JMeter в графічному режимі — отримав ті самі результати, лише в процесі роботи він використовував на 1 ГБ оперативної пам’яті більше.
  9. Результати тесту Gatling не корелюють з результатами інших тулів (по кількості запитів та RPS)
  10. Результати тестів показали, що мій сервер має точку насичення у приблизно 500 запитів на секунду — при подальшому зростанні навантаження росте лише час відповіді

Test #2

Після першого тесту я вирішив провести ще одну серію тестів «полегше», що перевірити поведінку тулів та їх результати. Дані тесту:
  • 500 users
  • 1 GET request
  • Expected result — HTTP 200 OK
  • пауза між викликами 1-2 sec
  • Ramp time — 10 sec — лінійне зростання навантаження
  • Час тесту — 2 min
Metric Locust JMeter Gatling
Throughput (RPS)330235269
Average response time, ms305027
Median response time, ms14610
Test PC RAM, Mb591 2801 252
Test PC Threads14 528 84
Total requests36 73127 80532 335
Success rate, %100100100

Нотатки:

  1. Незважаючи на те, що за однаковий час всі тули зробили приблизно однакову кількість запитів, я отримав різні результати Throughput та response time. Припускаю, що результати залежать від методу підрахунку а також від швидкості роботи HTTP клієнтів тулів

Висновки і плани

Чисто суб’єктивно, мені серед усіх тулів більше за все подобається працювати з Locust (люблю python). Також приємними бонусами є швидкість роботи та невелика кількість ресурсів, необхідна для роботи.
JMeter — класика, проста і зрозуміла, і необхідна у випадках, коли треба тестувати не HTTP протоколи :)
Найменше мені сподобався Gatling — що не зміг продемонструвати в моїх досить специфічних тестах ані економії ресурсів, ні більш менш релевантних результатів. Більш того, для його роботи необхідно мати одну специфічну версію Scala (і, знову ж таки суб’єктивно, мені не сподобався принцип написання тестів Gatling у вигляді ланцюгів викликів)

Об’єктивно: під кожну задачу треба правильно обирати тул та схему навантаження. Не кожен може давати велику потужність з одного ПК — можна скористатись можливістю розподіленого навантаження (JMeter та Locust можуть). Під час написання статті знайшов дослідження JMeter з оптимальної кількості юзерів

Всім, кому цікаво, можуть взяти код і спробувати провести свої тести — проект на Github. Якщо маєте рекомендації чи побажання — пишіть в коментарях.

У мене ще є нереалізовані ідеї, про які я хочу написати пізніше, якщо вам цікаво:

  1. Перевірити, як працюють мої тести в wsl2 — я вже намагався їх запускати в минулому і ОС просто зависала. Якщо результати будуть позитивними — провести тести з Yandex-tank (його дуже хвалили в коментах до моїх попередніх статей) та tsung
  2. Розробники Locust додали в новій версії новий fast http клієнт. І мені дуже кортить дізнатись, наскільки він швидший за звичайний (python requests)

А ще ми з колегами ведемо телеграм канал про тестування t.me/qamania — заходьте, ми намагаємось щодня писати щось цікаве про нашу професію

👍ПодобаєтьсяСподобалось1
До обраногоВ обраному8
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

бро, ранати такі тулзи з віндози це як тестувати автобан трактором
віндоза тупить на масове створення нових тредів, виділення памяті , etc
...подумавши...
інформаційно, як огляд тулзів, стаття хороша , дякую

так, в офіційних гайдах до всіх тулів є рекомендація виконувати тести в Linux. Але, як то часто буває, користуємось тим, що маємо. І Windows поводить себе в тестах не так і погано, а для невеликих навантажень ви навіть різниці не побачите

Коментар порушує правила спільноти і видалений модераторами.

Пост — хороший пример того, что нагрузочным тестированием (впрочем, как и любым другим) должны заниматься люди, которые понимают, что они делают. Что тестировал автор, зачем, о чем выводы?

Ну вот взять Test #1. Возможно, стоило разобраться откуда взялся такой странный Success Rate? Ведь если разобраться, то окажется, что каждый из инструментов в этом тесте, вообще, тестировал что-то свое. Locust, например, делает запросы асинхронно в рамках небольшого количества TCP соединений, и он единственный, кто тестировал само приложение. JMeter же, наоборот, открывает новое TCP соединение для каждого пользователя, и в этом случае он тестировал производительность TCP/IP стека в операционной системе, а приложение совсем не при чем. С Gatling та же история. Как можно делать какие-либо выводы о производительности инструмента игнорируя потребление ресурсов на стороне SUT — загадка загадочная?
Или Test #2. Среднее вдвое выше, чем в Test #1 не наводит ни на какие мысли?

В целом, вопросы здесь к каждой строчке, а читателю этот пост, в лучшем случае, ни чем не поможет, а скорее навредит.

Дякую за критику. Люблю коли вона констуктивна — тоді вчусь чомусь новому. Саме тому ми всі тут :)
Тепер до суті

откуда взялся такой странный Success Rate?

власне, мене це теж бентежило — і перші тести показували поганий результат для всіх тулів. Пошуки в інеті вказують, що для декстопних ОС часто за замовчанням доступно 1024 відкриті одночасні мережеві з’єднання. І помилки тули видавали відповідні, типу connection cannot be created.
Саме тому в передумовах тесту я роблю зміни в реєстрі, відкриваючи 65к з’єднань (впевнений ліміт є не просто так і мінуси в його збільшенні теж є, але поки не знайшов)
Всі тули після правки реєстру показують в результатах єдину помилку — connection timeout.
Тому на 99% впевнений, що не тестую TCP/IP стек.
Що ж до Success Rate — я думаю, різниця дійсно в http-клієнтах та підходах до навантаження різних тулів. Саме про це стаття — варто знати, який тул що може.

Как можно делать какие-либо выводы о производительности инструмента игнорируя потребление ресурсов на стороне SUT — загадка загадочная?

Мета була інша — перевірити поведінку тулів, а не тестувати продуктивність SUT, про що чесно написано напочатку. Тому і метрики SUT тут будуть не доречні — тестили інше. І якщо поведінка SUT — константа для всіх тулів і тестів, чи не все рівно? Якщо вам просто цікаво — відмітки у 100% CPU та RAM на сервері я не досяг.

Или Test #2. Среднее вдвое выше, чем в Test #1 не наводит ни на какие мысли?

Test #2 (Jmeter) 0,5 sec < Test #1 (Jmeter) 15.6 sec
Перепрошую що ввів в оману, для результатів другого тесту змінив одиниці виміру, оскільки величини менші.

В целом, вопросы здесь к каждой строчке

Не соромтесь, задавайте ;) Я на карантині здичавів, залюбки з кимось подискутую. Взагалі, може го дебати по перформанс тестуванню влаштуємо?

а читателю этот пост, в лучшем случае, ни чем не поможет, а скорее навредит.

тільки неуважному ;)

Тому на 99% впевнений, що не тестую TCP/IP стек.

На стороне NAS TCP/IP стека нет?

Якщо вам просто цікаво — відмітки у 100% CPU та RAM на сервері я не досяг.

Это совсем не праздное любопытство. Если CPU/RAM/IO на стороне сервера уперлись в 100%, то тестируете вы, что угодно, но не производительность нагрузочного инструмента.
Теперь о процентах. А что они вам показывают? В вашем процессоре 4 ядра, ваше Python приложение работает в одном потоке, в итоге при загрузке CPU в 25% ваши тесты становятся совершенно нерепрезентативными. Но опять же, не одними процентами... курите и LA параллельно.

Теперь о SUT. Зачем для тестирования raw производительности инструментов вам нужно какое-то мифическое приложение? Чем не угодил nginx и статический файл? Вот в такой конфигурации замучаетесь его убивать любым инструментом, даже на вашем полумертвом атоме (хотя это не точно, атом такой атом)

Test #2 (Jmeter) 0,5 sec < Test #1 (Jmeter) 15.6 sec
Перепрошую що ввів в оману, для результатів другого тесту змінив одиниці виміру, оскільки величини менші.

Теперь расскажите, как при среднем времени ответа в 10,5 секунд и 533 RPS вы получили 114к запросов за 3 минуты?

Не соромтесь, задавайте ;)

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

Expected result — HTTP 200 OK

Как это проверялось?

Ramp time — 20 sec

Почему так мало? Отброшены ли из средних и медиан данные из рампапа? Что насчет тиардауна, после 3х минут просто все убивалось или дожидались окончания всех запросов? Результаты тиардауна отброшены?

Результати тестів показали, що мій сервер має точку насичення у приблизно 500 запитів на секунду

Как, вообще, такой вывод получился? Не вижу ничего, что на него бы указывало.

И т.д. и т.п.

На стороне NAS TCP/IP стека нет?

Я не розумію питання. Точніше, відповідь на нього — так, є. І що далі? Спочатку мова було про стек клієнта. Тепер про стек NAS. Попереджуючи наступне питання — в мене між ними в мережі ще й роутер є. Визначтесь, що саме вас цікавить.
Якщо ваше питання — натяк на те, що перформанс сервера може впиратись в його TCP/IP стек — може й так. Якби мета тесту була заміряти його перформанс (що не так) і проаналізувати ботл неки — тоді це б мало більше значення. Повторюсь — мета тестів написана вище

Это совсем не праздное любопытство. Если CPU/RAM/IO на стороне сервера уперлись в 100%, то тестируете вы, что угодно, но не производительность нагрузочного инструмента.

без аргументації це ствердження нічого не варте. Крім того, як я писав вище, 100% не досяг

Теперь о процентах. А что они вам показывают? В вашем процессоре 4 ядра, ваше Python приложение работает в одном потоке, в итоге при загрузке CPU в 25% ваши тесты становятся совершенно нерепрезентативными

Не фокусував увагу на цьому окремо (просто написав docker файл) — python додаток крутиться за допомоги gunicorn в 4 worker’и (4 unix процеси) і може використовувати всі 4 ядра. І доречі, не пам’ятаю, чи писав раніше, що поведінка серверу для всіх тестів є константою?

Но опять же, не одними процентами... курите и LA параллельно.

Розшифруйте LA, будь-ласка. Бо я взагалі більше за бухати, ніж курити... (додав наприкінці три точки, щоб здаватись загадковішим)

Теперь о SUT. Зачем для тестирования raw производительности инструментов вам нужно какое-то мифическое приложение? Чем не угодил nginx и статический файл? Вот в такой конфигурации замучаетесь его убивать любым инструментом, даже на вашем полумертвом атоме (хотя это не точно, атом такой атом)

Бо так захотів — мені, як мінімум, весело було. І чому міфічне? Всі сорси є — качай, збирай. А в чому проблема? Частіше проводжу тестування саме додатків, а не статичних файлів. Ну і головне що? — однакова поведінка у всіх тестах
А ще в мене не атом, а гордий Celeron :D Ви точно уважно читали статтю?

Теперь расскажите, как при среднем времени ответа в 10,5 секунд и 533 RPS вы получили 114к запросов за 3 минуты?

Не бачу, в чому проблема — я навіть відео з пруфами записав. Ви не плутаєте throughput із bandwidth?

Смысла в этом как-то не вижу. Результаты эксперимента вызывают большие сомнения по причинам указаным выше, поэтому остальные вопросы можно разве что для троллинга задавать

причини, вказані вище, визивають великі сумніви :)
О, я думав, ви тролите з першого комента, типу «не читав, але засуджую». А ви то серйозно...

Expected result — HTTP 200 OK
Как это проверялось?

Ви серйозно?

Ramp time — 20 sec
Почему так мало?

Бо я лінивий і нетерплячий? Чи може проводив довші тести і отримав приблизно ті самі результати (за виключенням кількості реквестів)? Чи може загадковий...

Отброшены ли из средних и медиан данные из рампапа? Что насчет тиардауна, после 3х минут просто все убивалось или дожидались окончания всех запросов? Результаты тиардауна отброшены?

Для RPS — ніт. Так, це не правльно, але мета була інша (прям дежавю). Для ресурсів клієнта — так. Після завершення все вбивалось.

Как, вообще, такой вывод получился? Не вижу ничего, что на него бы указывало.

Приблизно.Не ставив мету точних вимірів цього параметру.
Якщо вас цікавлять точні характеристики — підписуйтесь наш телеграм канал та друзів приводьте — зроблю окремий пост, все чітко протестую та поділюсь ;)

Ну вот, а говорили, что

...тоді вчусь чомусь новому.

Спасибо, что в очередной раз напомнили почему не стоит ходить на QA конференции. Удачи вам на вашем нелегком пути.

Будь-ласка, не зливайтесь так банально, я дійсно хочу зрозуміти вашу позицію, підкріплену аргументами а не пустими фразами. І завжди готовий визнати, що не правий.

Пост — хороший пример того, что нагрузочным тестированием (впрочем, как и любым другим) должны заниматься люди, которые понимают, что они делают. Что тестировал автор, зачем, о чем выводы?

Інакше виходить, ваш комент — гарний приклад того, що будь-хто в Інтернеті може безпідставно критикувати будь-кого не розбираючись в темі.

в очередной раз напомнили почему не стоит ходить на QA конференции

прикро

В принципе, вы можете называть это «сливом» или любым другим словечком из вашего жаргона, но это точно не исправит ситцауию с вашим экспериментом. Если вы перечитаете написанное выше, то найдете достаточно аргументов, чтобы пересмотреть, то, что у вас получилось. Объясняю еще раз корото и тезисно, а вы уже решайте кто и куда «слился».
Итак:
— Для того, чтобы судить о производительности нагрузочного инструмента вы должны получить 100% утилизацию ресурсов (желательно CPU) на машине с которой вы подаете нагрузку и не уперется в 100% утилизации ресурсов на машине на которой находится ваш SUT, причем в случает SUT 100% утилизации не должно быть ни по одному из ресурсов — ни CPU, ни RAM, ни IO (в том числе и Network)
— Пункт #1 наводит нас на мысль о том, что SUT должен быть настолько быстрым и настолько стандартным (чтобы результаты были воспроизводимыми) насколько это возможно, поэтому ngnix и статический файл, куда лучше некого приложения, которое делает непонятно что и как. Опять же, ваш эксперимент не что-то супер уникальное, люди тут и там пытаются сравнивать инструменты нагрузочного тестирования, попробуйте посмотреть что они нагружают в этих тестах
— Что бы вы не думали, но я внимательно прочел статью и самого первого комментария говорю о TCP/IP стеке на стороне NAS. А проблемы с ним могут быть следующие — CPU просто не справляется с количеством соединений или это количество ограничено специально, что делается намеренно на практически любом NAS, потому как его задача шарить файлы, а не генерировать максимальное количество Hello World’ов в секунду
— Для того чтобы понять, что происходит с I/O вам и нужен LA == load average
— Все пункты выше прекрасно пояснют, почему в вашем тесте нельзя игнорировать SUT
— Лирическое отступление: ваш Celeron — переименованый Atom
— Утверждение о том, что ваш сервер может выдержать ~500 RPS следует из... ничего. Но вы уверенно берете это утверждение за основу для следующего теста
— Что касается «Expected result — HTTP 200 OK», то да, я серьезно. Ни одного assert’а в ваших скриптах нет, упоминания об анализе логов постфактум тоже нет, вы уверены, что любой другой HTTP код отразится на Success Rate? Еще вопрос для «подумать», а вы уверены, что все тысячи запросов вернули «Hello World»?
— Относительно Ramp Up Time. Я понимаю, что охота пуще неволи, но создание новых виртуальных пользователей очень дорогая операция и она влияет на потребление ресурсов на машине с которой подается нагрузка, а соответственно и на то, какую нагрузку этот инструмент может сгенерировать. И, главное, сами же говорите, что Locust не справился с этой задачей, но все равно сравниваете яблоки с апельсинами.
— Включать Ram up и Teardown в результаты замеров максимальной производительности неверно. Причин тому множество, подумайте хотя бы над тем, сколько стоит создание дополнительного VU для каждого из инструментов

Если написанное выше все еще осталось непонятным, то вы можете смело записать меня в «слившихся», т.к. я не вижу смысла в дальнейших пояснениях. Ну а пока ваша статья, как и ваш доклад не имеют ничего общего с заголовком. Более правильный заголовок: «Я написал три случайных скрипта для трех случайных инструментов, и вот что из этого получилось».

прикро

Почему же? Я, например, не хожу туда после того, как попал на доклад, где очень титулованый QA рассказывал, что веб сервисы пишутся на XML (это он про SOAP, если что) и о том, как они это XML чудо тестируют. А вы ж поймите, я же деньги за это заплатил. Вот приду туда, а там веб сервисы на XML, или замеры нагрузочного рандома или калькулятор опять тестируют, и при этом докладчик не склонен ни к критике, ни к анализу. Вот что мне там делать? Так что я только рад, и вы не жалейте :)

Респект! (ще одне словечко з мого жаргону)
Витратив деякий час за збір пруфів, але не жалкую — дізнався щось нове і через кілька днів напишу ще одну статтю, а вам дякую за ідею. А зараз детально:

— Для того, чтобы судить о производительности нагрузочного инструмента вы должны получить 100% утилизацию ресурсов (желательно CPU) на машине с которой вы подаете нагрузку и не уперется в 100% утилизации ресурсов на машине на которой находится ваш SUT, причем в случает SUT 100% утилизации не должно быть ни по одному из ресурсов — ни CPU, ни RAM, ни IO (в том числе и Network)

Тут знов питання до вас — чому?
Гарний приклад: при тестуванні завантаження ми відсікаємо від результатів ramp up та tear down time (а ще 5% та 95% -тилі), тому що результати будуть точніші.

Ваш приклад: треба отримати утилізацію 100% клієнта та не отримати 100% на сервері, тому що [брак аргументів]. Як це впливає? Я вам допоможу відповісти. Ранком прогнав 3 тести в JMeter по 6 хв, ramp — 2хв, 10к юзерів:
1) Як і попередні — python flask
2) nginx — офіційний docker image
3) не існуюча IP адреса в моїй мережі

Потім відсік від метрик ramp up та tear down time

І отримав, що в усіх 3-х тестах однакове використання ресурсів клієнта по CPU та RAM!
А докер контейнери в під час тесту показували навантаження до 20% CPU.
А мережевий інтерфейс серверу показав 0 помилок.
Звісно, RPS у всіх трьох випадках різний (чекайте пост, там бімба)

Висновок: говорити — не мішки ворочати. А в мене ще й пруфи є.

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

Я й не претендую на пальму першості. Різні цільові системи покажуть різні результати (у мене різниця між flask та nginx static майже в 10 разів)
Але знову ж таки, як бачимо, на результат це не впливає. А виб теж могли додати пруфи

Что бы вы не думали, но я внимательно прочел статью и самого первого комментария говорю о TCP/IP стеке на стороне NAS. А проблемы с ним могут быть следующие — CPU просто не справляется с количеством соединений или это количество ограничено специально, что делается намеренно на практически любом NAS, потому как его задача шарить файлы, а не генерировать максимальное количество Hello World’ов в секунду

0 помилок кажуть, що все ок

Для того чтобы понять, что происходит с I/O вам и нужен LA == load average

дякую за розшифровку

— Все пункты выше прекрасно пояснют, почему в вашем тесте нельзя игнорировать SUT

як бачимо — ніт

— Лирическое отступление: ваш Celeron — переименованый Atom

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

— Утверждение о том, что ваш сервер может выдержать ~500 RPS следует из... ничего. Но вы уверенно берете это утверждение за основу для следующего теста

чистий тес показав 520 — попередній раз я майже вгадав

— Что касается «Expected result — HTTP 200 OK», то да, я серьезно. Ни одного assert’а в ваших скриптах нет, упоминания об анализе логов постфактум тоже нет, вы уверены, что любой другой HTTP код отразится на Success Rate? Еще вопрос для «подумать», а вы уверены, что все тысячи запросов вернули «Hello World»?

by default тули для перформанс тестування оброблюють коди < 400 як ок.
Пруфи: docs.locust.io/...​d-successful-or-a-failure
gatling.io/...​s/current/http/http_check

І якщо не треба додаткові перевірки, assert’и можна не писати. Кажу це як людина, що практикує performance testing тому, хто очевидно тільки читав по нього

— Относительно Ramp Up Time. Я понимаю, что охота пуще неволи, но создание новых виртуальных пользователей очень дорогая операция и она влияет на потребление ресурсов на машине с которой подается нагрузка, а соответственно и на то, какую нагрузку этот инструмент может сгенерировать. И, главное, сами же говорите, что Locust не справился с этой задачей, но все равно сравниваете яблоки с апельсинами.
— Включать Ram up и Teardown в результаты замеров максимальной производительности неверно. Причин тому множество, подумайте хотя бы над тем, сколько стоит создание дополнительного VU для каждого из инструментов

як я вже писав раніше — метрики клієнта в статті написані без урахування Ram up та Teardown. А ви кажете, уважно читали

Если написанное выше все еще осталось непонятным, то вы можете смело записать меня в «слившихся», т.к. я не вижу смысла в дальнейших пояснениях. Ну а пока ваша статья, как и ваш доклад не имеют ничего общего с заголовком. Более правильный заголовок: «Я написал три случайных скрипта для трех случайных инструментов, и вот что из этого получилось».

Ні, мені з вами цікаво — коментуйте ще. А що до заголовка — він точний і у мене є докази. Я можу зробити ще більше тестів, якщо вже існуючих доказів недостатньо.

Не мішки ворочати...

Почему же? Я, например, не хожу туда после того, как попал на доклад, где очень титулованый QA рассказывал, что веб сервисы пишутся на XML (это он про SOAP, если что) и о том, как они это XML чудо тестируют. А вы ж поймите, я же деньги за это заплатил. Вот приду туда, а там веб сервисы на XML, или замеры нагрузочного рандома или калькулятор опять тестируют, и при этом докладчик не склонен ни к критике, ни к анализу. Вот что мне там делать? Так что я только рад, и вы не жалейте :)

Ліричний відступ — оскільки контексту мало, важко зрозуміти, хто тут Д’артан’ян. Маю 2 припущення:
1) Доповідач все розказував як міг, але не знав загальновживаної термінології (таке іноді трапляється навіть з титулованими). «веб сервисы пишутся на XML» == WSDL?
2) Він з колегами зробив з костилів велосипед — таке буває частіше ніж хотілося б. Всі їейтять велосипеди аж поки не починають працювати в такому проекті і тоді знаходять відмазки «ну в мене це інше», «в нас вибору не було». І хоча я на конфаг більше люблю доповіді про soft-скіли, такі доповіді теж цікаві саме тим, що наглядно показують, що буде, якщо не робити правильно і до яких проблем це приведе.

Аналогія: можна вчити ПДД і як водити машину правильно, а можна показати відео з серйозного ДТП, де кров, кишки і частини тіл — дієва демонстрація, нащо все робити за правилами, паттернами та за методологією

дізнався щось нове

Ну, это главное.

чому?

При 1 RPS Response Time 1 секунда, при 100 RPS — 10 секунд, а тестируем якобы инструмент для генерации нагрузки, а не SUT.

у мене різниця між flask та nginx static майже в 10 разів

То есть заменяем SUT, получаем разницу в 10 раз, но все равно утверждаем, что тестируем производительность инструмента для генерации нагрузки. Я ничего не перепутал?

А мережевий інтерфейс серверу показав 0 помилок.
0 помилок кажуть, що все ок

А на клиенте Connection Timeout все еще никуда не делся. Может нужно узнать еще что-то новое?

чистий тес показав 520

Где его увидеть этот «чистый» тест?

by default тули для перформанс тестування оброблюють коди < 400 як ок.

Тогда где же противоречие в моем вопросе? Я же и спрашиваю, как проверялось, что код 200, а не что-то другое меньше 400?

А в мене ще й пруфи є.
він точний і у мене є докази

«Усы, лапы и хвост — вот мои докУменты!»

XML
WSDL

Мимо. Попробуйте еще раз.

через кілька днів напишу ще одну статтю

Ждем-с

говорити — не мішки ворочати
Не мішки ворочати...
люблю доповіді про soft-скіли

Я смотрю, что доклады о софт-скиллах помогают :)

Где его увидеть этот «чистый» тест?

Легше, ковбой. І так почав ходити в коменти, як на роботу. Як писав вище, треба кілька днів, щоб оформити дані, записати відео, в перрвах між роботою та домашніми справами

При 1 RPS Response Time 1 секунда, при 100 RPS — 10 секунд, а тестируем якобы инструмент для генерации нагрузки, а не SUT.

у мене різниця між flask та nginx static майже в 10 разів
То есть заменяем SUT, получаем разницу в 10 раз, но все равно утверждаем, что тестируем производительность инструмента для генерации нагрузки. Я ничего не перепутал?

тобто вас хвилюють RPS в результатах? Можна їх прибрати (я не буду, інакше контекст втратиться). Just ignore. Мої тести (JMeter) показують, що SUT для ресурсів тула значення не має (для Gatling та Locust ще не перевірив). За весь час наших суперечок могли б самі тест який провести і довести свою правоту. Більш того, помітив що JMeter виділяє RAM та threads на самому початку тесту, незалежно від часу на ramp. Припускаю, для того, щоб ресурси випадково не скінчились посередині тесту

Тогда где же противоречие в моем вопросе? Я же и спрашиваю, как проверялось, что код 200, а не что-то другое меньше 400?

В моєму конкретному випадку це не має сенсу. Підкажіть, в якому кейсі flask сервіс, запрограмований повертати 200 ОК, чи офіційний nginx docker, що з коробки відповідає статичною сторінкою з кодом 304 — може повернути інший код < 400?
Мене колись студенти спитали, як ми можему довіряти програмістам, використовуючи класи еквівалентності — хто зна, що там накодили? Якщо вже є інпут для цілих чисел від 0 до 100 000, треба перевірити кожне число. Так і ви пропонуєте робити зайві перевірки, не аргументуючи, чи є імовірність отримати false positive

Ліричний відступ: звісно, в своїй практиці я писав тести, що валідували payload, щоб визначити, що респонс ок, так само як і робив тести, що очікували отримати HTTP 400, але явно не в цьому разі

«Усы, лапы и хвост — вот мои докУменты!»

докумЕнты!
пруф: www.youtube.com/watch?v=Sk0taJn5dyU

Мимо. Попробуйте еще раз.

¯\_(ツ)_/¯ замало інфи, щоб робити висновки

Я смотрю, что доклады о софт-скиллах помогают :)

карантин-driven коментування

Легше, ковбой.

Какой вы дерзкий :)

тобто вас хвилюють RPS в результатах? Можна їх прибрати (я не буду, інакше контекст втратиться). Just ignore. Мої тести (JMeter) показують, що SUT для ресурсів тула значення не має (для Gatling та Locust ще не перевірив).

Что-то я не могу понять в чем же вы измеряете производительность нагрузочного инструмента? В количестве потребленной памяти и созданных тредов?

Смішно буде коли виявиться що при 1 юзері показники такі ж як при 500, на таку залежність я б подився;)

Теж стало цікаво. Перевірю пізніше і напишу

Дякую за статтю! Дуже приємно бачити на DOU цікавий та корисний контент.

З приводу питання «А чому не спробували <щось>», можу запитати, чому не спробували k6? Було б цікаво додати його до порівняння.

k6.io/open-source

Я бы не сказал, что Gatling хуже JMeter. По мне, так даже лучше. Модель нагрузки в JMeter основана на многопоточности, а Gatling использует под капотом akka, которая будет потреблять меньше ресурсов. Выбор между JMeter и Gatling лучше основывать по таким параметрам как:
* использовать выделенный GUI (JMeter) или IDE/текстовый редактор + command line/maven/gradle/sbt (Gatling)
* в JMeter большее сообщество и большее количество плагинов
* если надо написать сложную логику формования/парсинга тестовых нагрузочных данных, то для Gatling надо знать scala хотя бы на среднем уровне

я й не писав, що він гірший. знаю людей, які ним користуються. І по споживанню ресурсів він показує себе краще JMeter. Але мені, суб’єктивно, він не подобається

Найменше мені сподобався Gatling — що не зміг продемонструвати в моїх досить специфічних тестах ані економії ресурсів, ні більш менш релевантних результатів.

Я так и не понял, какую вы хотите нагрузку на сервер — детали не описаны, особенно разница между разными тулами (видео не смотрел). Например, если вам интересно RPS, то для Gatling вам надо было использовать rampUsersPerSec вместо rampUsers.

для серверу — benchmark, оскільки очікувань не було. Але головна мета була подивитись за поведінкою самих тулів

rampUsersPerSec вместо rampUsers

дякую, я спробую

Спасибо за статью! Не планировали расширить тест фреймворки, скажем, Siege, Artillery,
Hey
, Yandex Tank? Или может написать обзор по зоопарку инструментов тестирования и когда какой лучше применять?

Не планировали расширить тест фреймворки, скажем, Siege, Artillery,
Hey, Yandex Tank?

так, в планах було

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

холіварна буде тема. я навіть починав — часу на все не вистачає

среднее время отклика для hello world — десятки секунд(?)

Test PC RAM, Gb 1280

. потерялась

среднее время отклика для hello world

якщо мова про перший тест — 10 секунд, мені здається, гарний результат, за умови докера і не дуже потужного серверу.
В результатах другого тесту допустив помилки з величинами, вже виправив, дякую за уважність!

круто ! дуже крута стаття ! Сам давно цим цікавлюсь і думав над подібним проектом.
Дуже дивно побачити такі відхилення по RPS та response time. Цікаво би знайти корінь проблеми і як зрозуміти, що ці дані корелюються з реальними метриками кінцевих користувачів.
Моя думка, що це може бути проблема з NAS або мережею. Було би круто задеплоїти кудись в клауди і спробувати там

я теж в першу чергу підозрював енв, але в такому випадку я мав бі різні результати навіть для одного і того самого тула, але результати ідентичні. Для цього дослідення я проганяв всі тести по 3 рази, для попереднього ще більше.
Моя думка — результати залежать від реалізації http клієнту та багатопоточності. Теж цікаво, як ці результати будуть корелювати з реальним використанням.
Можна спробувати провести distributed тест, що менше навантажить клієнти і має показати більш чистий результат

я проганяв всі тести по 3 рази

оо. хотів запропонувати це. а в таблицях середній результат за всі прогони ? чи якоїсь однієї ?

від реалізації http клієнту та багатопоточності

скоріш за все. + можливо, ще метрики по різнову оцінюються. Я колись копав у доках Jmeter, то там Response time рахується від надсилання першого пакету tcp, до отримання першого пакету. Можливо інші тули це по іншому рахують

в таблицях середній результат за всі прогони ? чи якоїсь однієї ?

за 2й. На першому зібрав початкові дані. На другому записував відео, 3й був контрольний. Оскільки різниця була незначна, не вираховував середнє значення

можливо, ще метрики по різнову оцінюються

ще минулого року, коли порівнював, помітив, що Gatling та JMeter по різному враховують Connection timeout. Склалось враження, що Gatling їх не враховує в середнє значення відповіді, а JMeter враховує як максимальний час відповіді.До речі, теж цікава тема для дослідження

Дуже цікаво, дякую за статтю!

Підписатись на коментарі