Задача как бы тривиальная, но, вот самое сложное в такого рода задачах - это выбрать инструмент. Итак приступаем. После получаса общения с поисковой системой у меня насобирался списочек различного рода утилит. И первую, которую я решил попробовать – это младший брат soapUI, под названием loadUI. В общем, я эту штуку скачал, установил, запустил, немного подождал, увидел пользовательский интерфейс и понял что это не то что мне нужно. Интерфейс, не ужасный, очень даже красивый, и, наверное, даже слишком для такой утилиты, просто я его не понял. Половина экрана занимает раздел с устаревшими новостями и всё как-то уж очень медленно работает. Закрыв его подальше, я решил посмотреть нет ли в soapUI того что мне нужно, т.к. где-то краем глаза видел что эти две утилиты интегрируются. И мне повезло - оказывается есть ! И уже давно есть, просто раньше я не обращал внимания на то что когда импортируешь WSDL чудесной галочкой можно скачать чтобы soapUI сгенерировал набор тестов:
И следующим шагом указать настройки для генерации тестов. Для функциональных тестов мне подошёл один тест кейс в котором включены обращения к обоим методам моего веб сервиса.
Внизу самая полезная галочка, это генерация нагрузочного теста на основе функционального.
Вот как выглядит то что получилось в дереве проекта:
Теперь, когда шаблоны тестов созданы, можно приступить к эмуляции логики клиента.
В моём случае всё достаточно просто: клиент через определённые интервалы времени обращается к методу ApproveSession для подтверждения сессии и в конце работы принудительно закрывает свою сессию с помощью TerminateSession. Всё просто, но есть два нюанса:
1. Необходима поддержка HTTP сессии с помощью Cookies
2. Каждый клиент должен присылать свой уникальный ключ на сервер, который в идеале ещё и должен бы быть закриптован
Итак, оказалось, что первый пункт легко разрешается с помощью ещё одной волшебной галочки, а именно:
Разобравшись с первым вопросом я приступил ко второму. После получаса рысканья по просторам интернета, нашёл очень полезную статью, которая реально сэкономила мне немного времени, и теперь я с радостью потрачу его на блог :)
Итак, применительно к моему случаю, SOAP запрос на подтверждение сессии выглядит приблизительно следующим образом:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> <soapenv:Header/> <soapenv:Body> <tem:ApproveSession> <tem:token>?</tem:token> </tem:ApproveSession> </soapenv:Body> </soapenv:Envelope>
Чтобы обеспечить уникальнсть ключа, я буду использовать индекс потока в котором запускается клиент, выглядит это так:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> <soapenv:Header/> <soapenv:Body> <tem:ApproveSession> <tem:token>token${=context.getProperty("ThreadIndex")+1}</tem:token> </tem:ApproveSession> </soapenv:Body> </soapenv:Envelope>
Теперь, когда запросы готовы, можно добавить несколько повторов (к сожалению, не знаю как можно организовать цикл в SoapUI, если кто подскажет – буду признателен), задержки между ними и запустить нагрузочный тест:
Итак, в результате запуска теста, получен полезный отчёт. Каждый шаг был выполнен 501 раз (колонка cnt) на протяжении интервала тестирования в одну минуту. Этот интервал я установил перед запуском теста. Кроме того, среднее время отклика сервера в пределах 250 мс (колонка avg), при этом максимальное время отклика порядка 1 сек, а минимальное - 100 мс. Очень неплохо при параллельной работе 500 нагрузочных клиентов. Суммарный объём трафика для всех клиентов менее 1 мб, при этом не было ни одного отказа. В целом результат меня удовлетворил. К сожалению, не получилось сэмулировать большее количество клиентов. При попытке запустить 1000 проходит всего 50 первых запросов а дальше в лог возвращаются ошибки соединения и на короткое время пропадает доступ к интернету. Скорее всего исчерпываются свободные ресурсы на ноутбуке где я проводил тест. На сервер нареканий нет - в логах сервера всё чисто, а счётчики производительности показывают что все запросы были успешно обслужены. Но это уже детали.
Главное, что soapUI всё-таки полезная штука, и в который раз она меня выручает :)