Oops... your message was not sent

Your message has been successfully sent

тематические истории, основанные на опыте компании JetRuby
QA

Используем JMeter для тестирования производительности базы данных PostgreSQL

Представьте, что вы написали и зарелизили офигительное приложение. Но вместо того чтобы читать о нем восторженные отзывы, вы не успеваете читать сообщения от клиентов: не загрузилось изображение, не удалось завершить покупку или найти необходимый товар и т.д. Что же пошло не так?

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

Задача

Итак, на одном из проектов мы столкнулись с необходимостью мониторинга параметров базы данных, отвечающей за работу API. В качестве инструмента был выбран JMeter. Он должен был запускаться из командной строки, а результаты тестирования предполагалось выгружать в CSV формате. Далее они автоматически отправлялись в админ панель, где по ним строились итоговые графики.

Для работы с JMeter, его нужно скачать. Если инструмент установлен предварительно, следует проверить насколько актуальна текущая версия и при необходимости обновить ее до последней. Далее скачиваем и устанавливаем Plugins Standard set.

Это еще не все. Остался последний подготовительный шаг: нам нужен JDBC — драйвер для работы с PostgreSQL. Скачать его нужно здесь. Загруженный jar файл драйвера копируем в папку [jmeter directory]/lib. На этом подготовка заканчивается, и мы приступаем к созданию тестового сценария.

JMeter-1

 

Тестовый сценарий

Суть сценария достаточно проста. Мы берем типовые запросы выборки (SELECT), которые выполняются при вызове методов API на стороне клиента. Далее этот пул запросов обрабатывается Random Controller. То есть из общего набора каждый раз выбирается произвольный. В контексте компонентов JMeter запрос это компонент JDBC Request.

Итак, первый шаг это настройка соединения с базой данных в компоненте JDBC Connection Configuration. Все заполненные поля компонента можно оставить без изменений, работать будем только с секцией Database Connection Configuration. Здесь мы прописываем:

  • Database URL, место хранения базы данных (доменное имя или IP адрес) с указанием порта и имени базы данных — jdbc:postgresql://[host name or IP]:[port]/[database name];
  • JDBC Driver Class, используемый класс драйвера, в нашем случае это org.postgresql.Driver;
  • Username, имя пользователя;
  • Password, пароль;

Не забываем сохранять изменения в сценарии.

JMeter-2

 

Следующим элементом добавим Thread Group на один уровень с JDBC Connection Configuration.

В классическом случае можно было бы установить следующие значения в настройках Thread Group:

  • будем отправлять 60 пользователей, Number of Threads (Users) = 60;
  • в течении 60 секунд, Rump-Up period (in seconds) = 60;
  • и повторим это 5 раз, Loop count = 5.

То есть наш тест продлится 5 минут, всего будет отправлено 300 запросов, по 60 запросов в минуту. Но как говорилось выше, мы будем работать без UI, а JMeter будет вызываться с параметрами из командной строки. Именно для этого вместо обычных числовых значений, используется конструкция ${__P([parameter name],[default value])}, например:

  • в Number of Threads (Users) указываем ${__P(users,6)};
  • в Rump-Up period (in seconds) прописываем ${__P(duration,60)};
  • в Loop count прописываем ${__P(loopcount,1)}.

Сохраняем изменения. Теперь в командной строке можно использовать эти параметры следующим образом:

[jmeter-directory]/jmeter -n -t [path]/[jmeter-scenario-file-name].jmx -Jusers=5 -Jduration=60 -Jloopcount=3 -l [path]/[report-file-name].jtl

Как видно из примера, ко всем параметрам добавляется буква J в начало имени параметра. То есть в командной строке мы объявляем: Jusers, Jduration, Jloopcount.

Следующий элемент, который следует добавить в тестовый сценарий — это Random Controller. Он является дочерним элементом Thread Group. Здесь, кроме имени компонента и комментария настраивать по сути нечего.

Далее на один уровень с Random Controller добавим Listener компонент. У нас это будет Aggregate Report. В этом компоненте также ничего не нужно настраивать.

JMeter-3

Ну и последний шаг в создании сценария это добавление запросов. Они же — JDBC Request в терминологии компонентов JMeter.

Как говорилось выше, для решения прикладной задачи мы выбрали типовые запросы, которые отрабатывают при вызове методов API проекта. В принципе, можно работать с любыми типами запросов, не только с выборкой (SELECT). Но в нашей задаче мы ограничились исключительно выборками. И как показала практика, не стоит использовать более JDBC Request. Большее число ограничивает вероятность повторного вызова какого-либо запроса в течение одного тестового сеанса. А это очень важно, так как первая выборка обычно бывает самой медленной. И если она одна, то результаты времени ответа (отработки запроса) будут сильно искажаться в сторону увеличения.

Итак, нам нужно добавить не менее 5 и не более 20 JDBC Request с различными запросам (в нашем случае только SELECT). Все JDBC Request должны быть добавлены, как дочерние элементы к Random Controller.

JMeter-4

Тестирование

Давайте для начала пройдемся по полям компонента JDBC Request.

  • Statement (подготовленный/параметризированный запрос добавления или удаления)
  • Commit (сохранение изменений)
  • Rollback (откат изменений)
  • Autocommit(false) (отмена автоматического сохранения изменений)
  • Autocommit(true) (автоматическое сохранение изменений)
  • Edit (должно быть ссылкой на переменную, которая принимает значение из указанных выше пунктов).

В поле Query может быть размещен, как статичный, так и динамичный запрос. Второй вариант интереснее, с точки зрения создания нагрузки. Ведь если параметры всегда меняются (например, выборка по ID), мы знаем что текущий диапазон ID интересующих нас объектов начинается с 1 и заканчивается 2036. В таком случае нам удобно использовать в запросе функцию __Random:

SELECT “organizations”.*

FROM “organizations”

WHERE “organizations”.”id” = ${__Random(1, 2036)}

С помощью Parameter values можно задать значения параметров. В поле Query параметры указываются, как знак вопроса. В поле Parameter types можно задать типы параметров. Параметры и типы параметров указываются через запятую. Например у нас есть запрос:

SELECT «organisations».*

FROM «organisations»

WHERE “organizations”.”id” = ?

AND “organizations”.”city” = ?

В таком случае в поле Parameter values мы можем записать например: 10, London. А в поле Parameter types соответственно: INTEGER, VARCHAR. В поле Parameter values, опять же, можно воспользоваться функцией __Random, которая добавит разнообразия выборкам.

Поле Variable names позволяет задать список переменных для сохранения данных, которые возвращают JDBC Request. Разделителем для списка переменных является запятая.

Поле Result variable name, если значение указано, создается переменная Object со списком карт строк. Каждая карта содержит имя столбца в качестве ключа и данные столбца в качестве значения. Пример использования:

columnValue = vars.getObject(«resultObject»).get(0).get(«Column Name»);

Поле Query timeout (s) не таит ничего экстраординарного. Если значение указано, добавляется задержка, с которой будет выполнен запрос.

Поле Handle ResultSet используется для работы с хранимыми процедурами Callable Statement и определяет, как будет обрабатываться результат:

  • Store As String (default) — значения переменных будут сохранены в списке в виде строк;
  • Store As Object — переменные будут сохранены, как объект;
  • Count Records — будет выполнен подсчет записей и переменные будут сохранены, как строки.

Вернемся к основной задаче. У нас уже есть сценарий, и мы можем запускать JMeter в командной строке. Но в результате мы получаем отчет в формате jtl, а нам нужен csv. Для того чтобы конвертировать данные, собранные листенером Aggregate Report в csv, нам пригодится один из плагинов Plugins Standard set. Он называется CMDRunner. Вызываем JMeter:

[jmeter-directory]/jmeter -n -t [path]/[jmeter-scenario-file-name].jmx -Jusers=5 -Jduration=60 -Jloopcount=3 -l [path]/[report-file-name].jtl

И конвертируем jtl в csv следующим образом:

java -jar [jmeter-directory]\lib\ext\CMDRunner.jar —tool Reporter —generate-csv [path]/[aggregate-report-file-name].csv —input-jtl [path]/[report-file-name].jtl

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

Вывод

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

JMeter-5JMeter-6

Подводя итог, хочется отметить основные преимущества JMeter:

  • Гибкость. Вы можете подгонять JMeter под любые задачи, включая автоматизацию тестирования.
  • JMeter поддерживает различные протоколы, включая FTP, HTTP, SOAP, JDBC, JMS и LDAP.
  • JMeter является open source проектом, а значит он загружается бесплатно.
  • JMeter очень прост в использовании. Все, что вам нужно сделать — это загрузить его, установить и запустить!
department
Статью подготовил
Отдел обеспечения качества
Профессиональное тестирование программного обеспечения. Мы используем самые эффективные практики и системы управления, гарантирующие наивысшее качество вашего продукта.
New Articles