воскресенье, 6 ноября 2016 г.

Тестирование TCP-сервиса из Jmeter

Доброго времени суток!

Постановка проблемы:

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

Решение:

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

Что нам предлагает Jmeter? Он нам предлагает из коробки только TCP Sampler
Но по умолчанию данный семплер посылает строковый запрос по TCP-соединению и получает строковый ответ. Этот режим суперски подойдет для протоколов которые работают в строковом режиме, к примеру, SMTP. В постановке задачи стоит не большая оговорка, что тестируемый нами сервис на вход принимает бинарную посылку и на выход отдает такую же бинарную посылку.
Гуглим... Читаем родную инструкцию  и понимаем, что семплер-то не так прост и имеет из коробки три реализации. Причем одна из них ровно то, что нам надо BinaryTCPClientImpl.
Что она умеет? Она умеет  читать из текстового поля семплера HEX строку, конвертировать ее в бинарную посылку и отправлять. Причем эта же реализация умеет принимать бинарный ответ, конвертировать его в HEX и выдавать его на экран в поле ответа. Как говорится "Вау!!! Оно!". Проблемы конвертации исходных данных из bin в hex описывать не буду. Решение этой проблемы тривиально. Качаем конвертер и конвертируем. По факту нужен Hex-dump бинарного файла. Единственный нюанс, так это то, что Hex-данные должны быть одной строкой. 
Настраиваем семплер, т.е. в параметре TCPClient classname указываем BinaryTCPClientImpl . В Text to send помещаем нашу Hex-строку и отправляем. В остальных параметрах указываем адрес нашего сервиса, порт по которому он отвечает и снимаем галочку Re-use conection, т.к. нам это соединение после того как получим ответ больше не нужно.
На этом можно было бы и закончить описание, если бы не факт того, что это работает не всегда. К сожалению TCP Sampler реализован криво и на этом мнение сходится определенная часть интернет-сообщество. Мне не повезло. У меня с начала заработавший тест-план после обновления ПО на сервере перестал вдруг работать.  
Симптомы: Соединение поднимается. Ответ от сервиса получается, но само соединение после получения ответа не закрывается. Соединение ждет таймаута на ответ и тест падает. Понятно, что о нагрузке в таком случае говорить не приходится. Если бы нужно было тестировать функциональность я бы еще как-то с этим смерился бы, но нагрузочное тестирование - это не об этом.
Гуглим... ) "Да проблема такая есть. Решать ее надо написанием собственного класса на базе, к примеру, того самого BinaryTCPClientImpl, но с перегруженным методом чтения из потока, т.к. TCPClient контролирует соединение и разрывать его когда получил все данные. А узнать он об этом сможет из ответа сервера, т.е. в ответе сервера как правило есть информация о длине пакета." Когда вот все, что выше написанное улеглось в голове у меня были глазки очень широко открыты и один чуть подергивался. Причина простая. писать свой класс для Jmeter? КАК??? Это отдельная история и я ее опишу отдельным постом. И так. решение проблемы семплера кроется в переопределение стандартного метода чтения из открытого соединения.
Создаем новый класс на основе BinaryTCPClientImpl (если кому интересно как именно переопределил метод, то все изменения доступны на GitHUB), пакуем его в jar, "подкидываем" jar в директорию %JMETER_HOME%\lib и запускаем сам Jmeter.
Открываем наш тест-план и в семплере, в параметре TCPClient classname прописываем название нашего нового класса.
Все остальное можно даже не менять. Запускам и...
РАБОТАЕТ!!!
На этом проблемы заканчиваются и далее делаем все как по учебнику, Навастриваем профиль нагрузки, проводим серии запусков, снимаем показатели. готовим отчет.

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

1 комментарий: