Привет всем!
Есть вопрос, буду благодарен за помощь.
Я заметил, что в моей панельке в графана неправильно выводятся percentiles и average response time, сравнивал я с агрегейт репортом в jmeter и html репортом.
У меня значения этих метрик отличаются в графана и агрегейт репорте / html репорте, моя query в influx:
SELECT
sum ( "count") as NumberOfSamples,
min (min) as Min,
max (max) as Max,
last (avg) as Average,
last ( "pct90.0") as Percentile90,
last ( "pct95.0") as Percentile95,
last ( "pct99.0") as Percentile99
FROM jmeter
WHERE "statut" = 'ok'
AND $timeFilter
AND transaction! ~ / (Setup) /
AND ( "application" = ~ / ^$application$ /)
GROUP BY "transaction"
Также я еще пробовал писать так:
percentile ( "pct90.0", 90) as "Percentile 90",
percentile ( "pct95.0", 95) as "Percentile 95",
percentile ( "pct99.0", 99) as "Percentile 99"
Значение percentiles конечно меняется, но оно все равно не совпадает с тем, что я вижу в агрегейт репорте, или в html репорте.
Также я пробовал раскомментировать в
jmeter.properties такие строки(font-bold), но это не помогло:
# BackendListener - configuration
#---------------------------------------------------------------------------
#
# Backend metrics window mode (fixed=fixed-size window, timed=time boxed)
backend_metrics_window_mode=timed
# Backend metrics sliding window size for Percentiles, Min, Max
backend_metrics_window=50000
# Backend metrics sliding window size for Percentiles, Min, Max
# when backend_metrics_window_mode is timed
# Setting this value too high can lead to OOM
backend_metrics_large_window=50000
Кто нибудь сталкивался с такой проблемой?
Уже общались по этому поводу в другом чате, но решил еще тут пошарить информацию, так как складывается ощущение что много кто не понимает как работает агрегация в стандартном influxdb backend listener.
На деле стандартный бекенд лисенер по дефолту агрегирует данные не за 5 секунд, как может показаться на первый взгляд, а немного по другому. Лисенер под капотом использует либу DescriptiveStatistics, которая позволяет получать в рантайме разного вида агрегации. Джиметр создает себе несколько датасетов:
- okResponsesStats
- koResponsesStats
- allResponsesStats
- pctResponseStats
По сути датасет это такой себе бакет, куда джиметр будет добавлять респонс таймы, а DescriptiveStatistics будет считать разные агрегации по требованию джиметра, например "koResponsesStats.getPercentile(percentile);"
У каждого датасета есть свой максимальный размер, который можно передать в
jmeter.properties файле.
В
jmeter.properties есть вот такие параметры:
# Backend metrics window mode (fixed=fixed-size window, timed=time boxed)
#backend_metrics_window_mode=fixed
# Backend metrics sliding window size for Percentiles, Min, Max
#backend_metrics_window=100
# Backend metrics sliding window size for Percentiles, Min, Max
# when backend_metrics_window_mode is timed
# Setting this value too high can lead to OOM
#backend_metrics_large_window=5000
Так вот, если максимальный размер датасета к примеру 100 и в него уже добавлено 100 значений, новое значение пойдет перетирать первое в нем и так далее.
А теперь разберем пример:
За первые 5 сек теста джиметр выполнил 2 запроса Login с респонс таймами 100 и 200мс
- okResponsesStats(100,200)
- koResponsesStats()
- allResponsesStats(100,200)
- pctResponseStats(100,200)
при отправке данных джиметр попросит DescriptiveStatistics посчитать avg, pct(90,95,99), min, max. Avg например получится 150мс, что и отправится в инфлюкс
Дальше за вторые 5 сек отправилось еще 3 запроса, один из них свалился, в итоге датасеты выглядят вот так:
- okResponsesStats(100,200,120,160)
- koResponsesStats(190)
- allResponsesStats(100,200,120,160,190)
- pctResponseStats(100,200,120,160,190)
при отправке данных джиметр попросит DescriptiveStatistics посчитать агрегации и либа опять посчитает их на основании всех данных что есть в бакете, то есть avg будет не по (120,160,190) а по всем (100,200,120,160), что тупо с точки зрения мониторинга, так как на графиках в графане я хочу видеть значения среднего как раз за промежутки в 5 сек, а не пересчитывание данных с начала теста.
Для того что б исправить это, нужно изменить значение проперти backend_metrics_window_mode с fixed на timed.
После этого джиметр начнет очищать датасеты okResponsesStats, koResponsesStats, allResponsesStats после каждой отправки данных в инфлюкс, что нам и нужно.
Теперь по поводу персентилей, датасет pctResponseStats не очищается при любых значениях backend_metrics_window_mode, так как персентили нас интересуют не за 5 сек, а за весь тест. Нас интересует последнее значение персентиля для транзакции, которое бекенд лисенер отправляет в инфлюкс. Основная проблема в том что значения не совпадают с тем что показывает джиметр это то что дефолтное значение backend_metrics_window=100, а это значит что 101 и все остальные семплы будут просто начинать перетирать 1,2... значения в pctResponseStats датасете, и в результате в конце теста лисенер посчитает персентиль только за последние 100 семплов. Для того что б значение персентиля было максимально правдивым, нужно поставить в backend_metrics_window большое значение, в идеале больше чем количество семплов что выполняются за тест. При таком раскладе до конца теста pctResponseStats будет в себе хранить все респонс таймы и сможет спокойно посчитать правильный персентиль.
Так что мой совет ставить timed и большие значения в оба backend_metrics_window и backend_metrics_large_window
Ура, но если проверите, то скажете что всеравно не работает, цифры отличаются от того что дает джиметр.
Что я только что протестил для демо: запустил тест на 100 семплов, отсортировал по убыванию респонс таймы и вот мои топ 12 запросов в мс:
155