Обновить
50
Вячеслав@polarnik

Performance Engineer

57
Подписчики
Отправить сообщение
vladimirsitnikov привет. Прорецензируй пожалуйста комментарий. Верно ведь указал сферу применения таймера Precise Throughput Timer и его параметры?
А всё-таки, на сколько серверов подаётся нагрузка? На 250+?
Понял подход. Можно гибче сделать. С одной катушкой и Throughput Controller-ами для блоков.

Тогда чтобы поднять нагрузку достаточно просто увеличить количество потоков в одной катушке и ничего не придётся пересчитывать в Excel. Это количество потоков удобно передавать в скрипт из вне. Взяв в качестве значения не константу 20, а property
${__P(NUM_THREADS, 20)}, которое уже задавать в параметрах запуска скрипта:


А чтобы не считать матожидания и, главное, не пересчитывать их в Excel при модификации скрипта. Можно просто положиться, что запрос выполняется не более 5 сек. И это значение можно сразу выставить в

HTTP Request Defaults: Response Timeout (4000) и Connect Timeout (1000)

И зная, что каждый запрос не более 5 сек. Рассчитать с округлением длительность всего сценария по верхней планке: пусть 50 запросов, значит 50*5=250 сек, а если с запасом, то 300 сек.

Чтобы не валить сервер, когда время отклика превысит 5 сек на запрос. Стоит поменять в катушке параметр Action to be taken after a Sampler error со значения Continue на значение Start Next Thread Loop.

После чего можно выставить шаг нагрузки. В 300 сек (6 минут). Используя Constant Througthput Timer:
  • Target Throughput (1/6): 0.1667
  • Calculate Throughput based on: this thread only

Посчитаем сколько запросов будет за сценарий:
  • Авторизация — 10 запросов — вероятность 1.0
  • Главная — 30 запросов — вероятность 1.0
  • Календарь — 20 запросов — вероятность 0.2
  • Блог — 70 запросов — вероятность 0.1
  • Файлы — 15 запросов — вероятность 0.05


Получилось, примерно:

10 * 1.0 + 30 * 1.0 + 20 * 0.2 + 70 * 0.1 + 15 * 0.05 = 51,75

А количество потоков в катушке рассчитать так, чтобы получился требуемый 1 млн запросов в 24 часа:
  • 1 000 000 / 51,75 запросов / 24 часа / 60 минут == 13,419216318 запусков сценария в минуту нужно сделать для интенсивности 1 млн в день
  • 0.1667 запусков сценария в минуту делается сейчас одним потоком
  • значит 13,419216318 / 0.1667 == 80,499198068 ~ 81 поток нужен


Примерный размер пула потоков мы нашли.

Так как значение 81 не очень большое, не 10к. То можно доверить финальный расчёт интенсивности умным таймерам. Добавив в пул не менее 81 поток. Например для постоянной нагрузки хорош точный таймер: Precise Throughput Timer.

Настроек у него немало. Но нам в общем понадобятся такие:
  • Target throughput (in samples per 'throughput period'): 1000000
  • Throughput period (seconds): 86400
  • Test duration (seconds): 86400

А в катушке нужно будет по прежнему задать не менее 81 поток, но плюс в том, что можно задать и больше. Например, 500. Таймер умный, и использует столько, сколько надо, чтобы получилась интенсивность 1 000 000 в сутки. А когда пул взят с запасом. То можно долгое время не пересчитывать нагрузку в Excel. Просто дорабатывать скрипт, добавлять в него запросы.

Про паузы. Precise Throughput Timer сам сделает паузы между запросами. Может сделать их случайными. И добавлять паузы искусственно не придётся.

В теории это так работает. Но, конечно, надо всё проверять.
Спасибо за статью. Очень понравился раздел «Интерпретация результатов нагрузочного тестирования», где отмечена важность анализа логов.

Технический вопрос про bitrix24. В скрипте нагрузка подаётся минимум на 250 серверов
load[1...250].bitrix24.[строки из csv-файла]
По факту, думаю, речь идёт про 500, 1000 серверов.
Это большая ферма.

Скриншот, где показан профиль нагрузки в 20 потоков и скриншот, где показан один график утилизации CPU, DISK,… тут показаны для примера? А реальная нагрузка подаётся с такой же большой фермы генераторов нагрузки (100 штук)?

Ещё. При таком большом количестве доменных имён есть смысл использовать DNS Cache Manager. Если интенсивнсть большая. Ведь по умолчанию JMeter не кеширует DNS-ответы, а клиенты (браузеры) кешируют. И на практике, это однажды ограничило нагрузку. Что стало сюрпризом. Ведь редко кто мониторит и DNS-сервер во время нагрузки.
Согласен, искусственные паузы между запросами и стремление к реальным пользователям за счет таких пауз увеличивают шаг нагрузки. Что и потребуют больше потоков при наличии требования к заданной интенсивности. Что часто приводит к ситуации 10к тредов.

Но у автора 20 тредов. Закрытая модель нагрузки. Фактически, интенсивность он напрямую не контролирует. А раз так, то можно добавлять любые паузы.

Профиль нагрузки
image

image


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

проверить уже невозможно. Будет сделано столько хитов, сколько выдадут 20 пользователей, которые работают в течение 86400 сек (24 часа). И тут может получиться, как 10 млн, так и 100 тысяч. Зависит от времени отклика системы и длительности пауз.
Отличный awk-скрипт. Тоже их люблю.

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

Например, в статье есть действия:
  1. Авторизация
  2. Главная
  3. Задачи
  4. Календарь
  5. Файлы
  6. Фотографии
  7. ...


Для стандартного формата access.log ngxin:
стандартный формат
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';


где поле '"$request" обрамлено двойными кавычками, поэтому если в качестве разделителя использовать двойную кавычку, то значение поля $request будет после первой и до второй двойной кавычки. То есть $request будет $2 элементом после разделения строки.

Пример:
127.0.0.1 - - [16/Jun/2019:21:30:16 +0300] "GET /icons/ubuntu-logo.png HTTP/1.1" 404 152 "http://localhost/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"



Можно использовать такой скрипт, чтобы посмотреть распределение операций:

(cat /var/log/nginx/access.log && cat /var/log/nginx/access.log.1 && zcat -qa /var/log/nginx/access.log.*.gz ) | awk -F '"' '{a[$2]++}END{n=asort(a,b);aMax=b[n];for(i in a){print a[i] " --- " (a[i] / aMax) " --- "  i}}' | sort -nr


Статистика, нормированная по самой частой операции. Как правило, самая частая операция — главная и авторизация.

И по полученной статистике вида
11 --- 1 --- GET /icons/ubuntu-logo.png HTTP/1.1
11 --- 1 --- GET / HTTP/1.1
1 --- 0.0909091 --- GET /favicon.ico HTTP/1.1


Настроить, используя компонент Throughput Controller, вероятности для блоков. И получится, что «Авторизация» и «Главная» имеют вероятность 1.0, а «Фотографии» и «Блог» имеют вероятность 0.0909091.
Спасибо, Герман. Интересные приёмы используешь, возьму себе:

  • вставка "%" для обозначения Throughput Controller;
  • циклы по переменным в Groovy-стиле:
    vars.entrySet()
    	.collect { it.key }
    	.grep { it.startsWith('can_') }
    	.each vars.&remove
  • передача функций через vars:
    vars.putObject('updateGrid', this.&updateGrid)
  • скрытый JSR223 через Flow Control Action + JSR223 PreProcessor;
  • метрики для определения качества autovacuum.


Не знаю, чем JSR223 Assertion лучше JSR223 PostProcessor. Проверить надо. Может и нет разницы.

У меня бы терпения не хватило столько JSR223 отлаживать. Их же постоянно править приходится. Поэтому все их выношу во внешние файлы. И пишу код в IDEA, так удобнее отслеживать версии, быстрее делать рефакторинг, искать код.

А вот этот код меня смущает:
// Portal Timer
def local = ${THREAD_COUNT};
def total = ${THREAD_COUNT_TOTAL};
...

Сейчас специально замерю, но думаю, что вот такой вариант будет быстрее, за счёт неизменности groovy-кода, и отсутствия даже возможности лишней перекомпиляции:
// Portal Timer
def local = vars.get('THREAD_COUNT');
def total = vars.get('THREAD_COUNT_TOTAL');
...


В Timing PostProcessor код не является потокобезопасным, так как props — это просто HashMap, нет блокировок, между моментами get и put данные изменятся несколько раз:
int samples = 5;

double oldAvg = props.get('portalRespAvg');
double newAvg = ((oldAvg * (samples-1)) + prev.getTime()) / samples

props.put('portalRespAvg', newAvg);

Но тут не знаю, что предложить взамен. Не писал таймеры.
Спасибо за ответ. Ощущение, что в статье что-то не рассказано, уменьшилось.

Здорово, что тесты не мигают. Важна история, что тестов много и на их поддержку уходит много времени. Как понимаю, это основная работа, значит команда — команда автоматизаторов. Редкая.

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

И если две такие команды встретятся и начнут обсуждать, что важнее в их работе. Одна будет говорить: «У нас нет сроков», — а вторая отвечать: «А у нас есть сроки, и всё просто замечательно». И обе правду говорят :). Значит критерий оценки не самый точный.

Работаю в команде, про которую ещё статей не написано. Команды гибкие. Ближе всего к команде из трёх человек. Мы просто делаем работу, делаем хорошо. Иногда мы обсуждаем сроки и приоритеты. Но это в те моменты, когда работы свалилось по 10+ задач на человека. А когда горизонт планирования 1-2 задачи на человека, а все остальные пока не важны, то обсуждения приоритетов нет.
Как правило, ответом на вопрос «успеем ли мы к заданному сроку» является аналитика и MVP, качественная инфраструктура разработки и размер технического долга, а именно сложность проведения рефакторинга и наличие автоматических тестов на регрессию.

Сколько тысяч автоматических тестов на поддержке сейчас? И сколько человек из 150 заняты этой задачей? Мигают ли они, сколько там технического долга?

Это вопросы с продолжением. Продолжение в том, что инфраструктура и автотесты не даются бесплатно. Если они работают всегда, без долгов, возможно, кто-то из команды с работы не выходит
Столкнулся с проблемой во всех реализациях работы с IBM MQ из JMeter (5.0):

Дублирующиеся client ID при работе JMS Point-to-Point и других компонентов JMeter
Основная ошибка в checkDuplicateClientID из com.ibm.mq.allclient-9.0.0.5.jar:
ERROR o.a.j.p.j.s.JMSSampler: JMSCC0111: IBM MQ classes for JMS attempted to set a pre-existing client ID on a Connection or JMSContext.
com.ibm.msg.client.jms.DetailedInvalidClientIDException: JMSCC0111: IBM MQ classes for JMS attempted to set a pre-existing client ID on a Connection or JMSContext.
  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_191]
  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_191]
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_191]
  at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_191]
  at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319) ~[com.ibm.mq.allclient]
  at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:226) ~[com.ibm.mq.allclient]
  at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:126) ~[com.ibm.mq.allclient]
  at com.ibm.msg.client.jms.internal.JmsConnectionImpl.checkDuplicateClientID(JmsConnectionImpl.java:304) ~[com.ibm.mq.allclient]
  at com.ibm.msg.client.jms.internal.JmsConnectionImpl.<init>(JmsConnectionImpl.java:252) ~[com.ibm.mq.allclient]
  at com.ibm.msg.client.jms.internal.JmsQueueConnectionImpl.<init>(JmsQueueConnectionImpl.java:67) ~[com.ibm.mq.allclient]
  at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:276) ~[com.ibm.mq.allclient]
  at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:236) ~[com.ibm.mq.allclient]
  at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6016) ~[com.ibm.mq.allclient]
  at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:111) ~[com.ibm.mq.allclient]
  at org.apache.jmeter.protocol.jms.sampler.JMSSampler.threadStarted(JMSSampler.java:664) [ApacheJMeter_jms-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.threads.JMeterThread$ThreadListenerTraverser.addNode(JMeterThread.java:762) [ApacheJMeter_core-5.0.jar:5.0 r1840935]
  at org.apache.jorphan.collections.HashTree.traverseInto(HashTree.java:994) [jorphan-5.0.jar:5.0 r1840935]
  at org.apache.jorphan.collections.HashTree.traverseInto(HashTree.java:995) [jorphan-5.0.jar:5.0 r1840935]
  at org.apache.jorphan.collections.HashTree.traverseInto(HashTree.java:995) [jorphan-5.0.jar:5.0 r1840935]
  at org.apache.jorphan.collections.HashTree.traverse(HashTree.java:977) [jorphan-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.threads.JMeterThread.threadStarted(JMeterThread.java:730) [ApacheJMeter_core-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.threads.JMeterThread.initRun(JMeterThread.java:718) [ApacheJMeter_core-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:249) [ApacheJMeter_core-5.0.jar:5.0 r1840935]
  at java.lang.Thread.run(Thread.java:748) [?:1.8.0_191]


Наведённая ошибка уже при работе с очередями:
ERROR o.a.j.p.j.s.JMSSampler: Error browsing queue queue://ManagerName/QName with selector  and configured timeout 20
java.lang.NullPointerException: null
  at org.apache.jmeter.protocol.jms.sampler.JMSSampler.browseQueueForConsumption(JMSSampler.java:331) [ApacheJMeter_jms-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.protocol.jms.sampler.JMSSampler.handleRead(JMSSampler.java:271) [ApacheJMeter_jms-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.protocol.jms.sampler.JMSSampler.sample(JMSSampler.java:204) [ApacheJMeter_jms-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:622) [ApacheJMeter_core-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:546) [ApacheJMeter_core-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:486) [ApacheJMeter_core-5.0.jar:5.0 r1840935]
  at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:253) [ApacheJMeter_core-5.0.jar:5.0 r1840935]
  at java.lang.Thread.run(Thread.java:748) [?:1.8.0_191]

При любых таймаутах и настройках.



Происходит например в строке
github.com/apache/jmeter/blob/v5_0/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/JMSSampler.java#L331
consumer = session.createReceiver(queue, jmsSelector);


Причина — если для фабрики соединений указать значение для Общие/Идентификатор клиента отличное от пустого. То в результате получается такая ошибка.

Исправление — не заполнять поле. В текущей статье, про него не написано, и это правильно.
Здравствуйте, Михаил. Хорошая тема.
В тестировании производительности использую более простые на мой взгляд способы.

Шаг 1. I'd like to run automated tests with reCAPTCHA. What should I do?
Site key: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
Secret key: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
Эти настройки указываются в конфигурационном файле сервера приложений.

Шаг 2. Настройка Fiddler и работы приложений через прокси-сервер. Так как сервер приложений всё равно будет отправлять запросы в Google, а Google для такой отладочной связки Site key + Secret key будет всегда говорить — ok. Можно автоматизировать процесс, сделать так чтобы сервер приложений работал с Google через прокси-сервер. А в прокси-сервере (использую Fidder) настроить автоответ на запрос.

2.1. Сохранить оригинальный ответ от Google ReCapcha.
2.2. Используя auto response в Fiddler сделать так, чтобы на все запросы к Google ReCapcha был фиксированный положительный ответ.

В ответе будет сказано, что результат проверки — ok. Но будет сказано, что время ответа было в прошлом. Если сервер приложений валидирует не только ответ true/false, но и время. То автоответ не сработает. Но, обычно, сервер приложений время не валидирует, что позволяет сделать замкнутую систему.

Таким образом, получаю полностью автономную систему. Которая не обращается в Интернет. И на которую можно подавать высокую нагрузку. Проверял на интенсивности до 50 сценариев в сек.
Спасибо за проект! Использую версию с sf.net: sourceforge.net/projects/ashv и очень доволен. Коллеги тоже.

Были сложности при подключении — jdbc драйвер был старым. А новый не загружался из lib. Коллега разобрался, как и что заменить. С тех пор всё работает.

Буду знать, что есть новая версия
Ещё заметил особенность загрузки SharedHashMap в JMeter 5.0. Возможно, это дефект загрузчика компонент. Если к классе SharedHashMap только статические методы, то методы класса нельзя вызывать из JSR-223 Sampler. И чтобы класс считался классом, добавил в него нестатический метод test(). Что будет делать этот метод не важно, важно, чтобы он был.

Код можно написать так:
import java.util.concurrent.ConcurrentHashMap;

public class SharedHashMap
{
	private static final ConcurrentHashMap instance = new ConcurrentHashMap();

	public static ConcurrentHashMap GetInstance()
	{
		return instance;
	}

	public String test() {
                return "SharedHashMap";
        }
}


Не исследовал пока почему так происходит. Поисследую

Отличная статья, Владимир. Много лет уже использую знания о том, что Groovy производительнее, чем некешируемый BeanShell.


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


О практике применения связанной работы потоков в Apache.JMeter и передачи параметров между ними можно отдельную статью написать:


  • через объект ConcurrentHashMap: put + get
  • через связку объектов LinkedBlockingQueue: put + take или put + pool и ConcurrentHashMap — хеш-таблица с очередями
  • возможно учитывая параметры ConcurentHashMap для повышения эффективности ( Как работает ConcurrentHashMap )
  • или используя другие комбинации: Обзор java.util.concurrent.*
  • про подготовку параметров в SharedHashMap на этапе работы setUp Thread Group + JSR223 Sampler
  • про проверку на наличие оставшихся в SharedHashMap данных на момент завершения теста в tearDown Thread Group + JSR223 Sampler, где используя объект SampleResult можно сгенерировать дочерние объекты с ошибками — невостребованными тестовыми данными (начиная с JMeter 5.0 подзапросы тоже попадают в csv-лог и отчёты, как самостоятельные сущности, поэтому не пропадут)
При подключении библиотек использую комбо-набор из:
  • com.ibm.mq.allclient.jar — 8,2 МБайт
  • fscontext.jar — 22,8 кБайт
  • jms.jar — 58,3 кБайт
  • providerutil.jar — 77,1 кБайт

Архив allclient содержит в себе многие отдельные компоненты. Проверил — это минимальный набор, необходимый для работы с IBM MQ из Apache.JMeter. Он короче набора, указанного в статье за счёт большого allclient.jar.

Пришел к нему из ответа Jmeter JMS point to point to connect IBM MQ error ( java.lang.IllegalStateException: QueueConnectionFactory expected, but got com.ibm.mq.jms со stackoverflow.

Библиотеки из ответа на stackoverflow ...
I believe you don't need that many jars, you should download the relevant 8.x.x.x-WS-MQ-Install-Java-All.jar package from the Fix Central and come up with libraries like:

com.ibm.mq.allclient.jar
com.ibm.mq.traceControl.jar
fscontext.jar
jms.jar
JSON4J.jar
providerutil.jar


Провалидировал. На сколько помню, com.ibm.mq.traceControl.jar есть в allclient.jar или просто не всегда нужная библиотека — активируется только в режиме трассировки, который редко используется для JMeter, ведь в этом режиме весь трафик между JMeter и IBM MQ пишется в файл, и тест становится медленным. А библиотека JSON4J.jar не нужна — не нашел её в последних сборках IBM MQ, и без неё работает тест.

Удобно, что в статье и библиотеки приведены. Одно пожелание — чтобы быстрее находили, не прятать их. Пусть список длинный, но будет виден.
Тоже оценил, что в JMS Publisher + JMS Subscriber есть разные форматы, есть возможность передать Object, который сериализуется в XML самостоятельно, прочитать файл — удобно. Думаю изучить эту связку.
Ещё раз спасибо
Предполагая, что JMS Publiser и JMS Subscriber предназначены только для топиков, а не для очередей. Что предположил после просмотра скриншота в документации на Publisher:
JMS Publiser: dinamicTopics/myStaticTopic1
dinamicTopics/myStaticTopic1
указано:
dinamicTopics/myStaticTopic1


И не читая саму документацию :). Не рассматривал связку Publisher+Subscriber для очередей.
А просто использовал для отправки и получения сообщений из IBM MQ компонент JMS Point-to-Point, который с очередями работает — проверено.

Есть ли отличие между
  • JMS Publisher + JMS Subscriber
  • JMS Point-to-Point (request_only) + JMS Point-to-Point (read)

в удобстве использования?

Статья отличная, спасибо!

Да, Вы правы. Есть районы, в частности, где соединяются транспортные потоки (вокзалы, электрички). В них повышенное количество пассажиров. Но так не везде, например, зелёная ветка свободнее фиолетовой, за исключением пересечений веток.


С другой стороны, в Ижевске умеют считать деньги, оптимизировать интервал работы транспорта. И там в троллейбусах и трамваях свободно — они помедленнее ходят, а в автобусах и маршрутках плотно — они ходят реже. Интервал подобран под поток пассажиров. Поток меньше — расписание реже.
Фактор этот важен — частота работы транспорта в Москве выше, чем в небольших городах. Интервал работы метро и автобусов центральных маршрутов небольшой — минуты (2 минуты для метро). И пропустить автобус, уехав на следующем свободном, в Москве стоит 5 минут, а не 15.


А чего не много в Ижевске, так это ночных маршрутов. Водил там машину во многом из-за того, что в 22:00 транспортное сообщение с моим домом прекращалось. Зашёл после работы в гости, и потом остаёшься или вызываешь такси. В Москве оно прекращается где-то в 01:30. Вход в метро закрывается в 01:00, переходы чуть позже, автобусы ещё позже. Но это важно не каждому.

Нашел ответ на свой вопрос в более ранней публикации: Работа с потоком логов в реальном времени с помощью Heka. Опыт Яндекс.Денег. Heka отправляет данные в ElasticSearch в реальном времени
И более простой вопрос. Про Concurrency Thread Group, который приведён на картинке. Таймеры используются вместе с этой катушкой? Throughput Shaping Timer можно использовать при наличии в сценарии транзакций, группирующих запросы?

Не использовал такую связку ранее, так как не мог понять, как считать для неё параметры. Инструкция по Throughput Shaping Timer огромна. И смущает, что надо задать RPS. В текущей статье описывается пример, когда нет транзакций, только запросы. Поэтому счётчик RPS будет точным. А у меня в работе много транзакций, и предполагаю транзакции дадут лишние (но на деле не выполняющиеся) запросы, завысив RPS. Поэтому и решил, что мне Throughput Shaping Timer не подойдёт.

И поэтому использую надёжную простую связку Utlimate Thread Group + Test Action + Constant Throughput Timer / Precise Throughput Timer. Опираясь на шаг для транзакций.

Или тут открытая модель нагрузки. Без таймеров, только количество потоков через Concurrency Thread Group. И все расчёты будут точны, если опираться на медианное значение времени отклика на проде?

Информация

В рейтинге
Не участвует
Откуда
Армения
Зарегистрирован
Активность

Специализация

Инженер по производительности
Ведущий
PostgreSQL
Java
Высоконагруженные системы
Kubernetes