Pull to refresh

Нагрузочное тестирование Web-систем. Продолжаем подготовку

High performance *Web services testing *
В статье описаны ряд моментов (количество соединений и последовательность выполнения, сторонние ресурсы в сценарии, группировка запросов), на которые стоит обращать внимание при подготовке к выполнению теста с высокой нагрузкой на Web-систему с Web-интерфейсом.

Предлагаю рассмотреть следующие элементы конфигурации сценария, которые могут повлиять на производительность вашего теста.

Хочу описать почему использование реальных методов HTTP важнее, чем его «быстрые» аналоги. Затронем необходимость использования проверок получаемых данных и выстраивание регулярных выражений для получения значений.

Получение ответов с реальным размером данных


По моему мнению, как минимум в финальном тестировании Web-системы необходимо использовать те запросы, которые отправляет браузер. Если это был GET запрос, то мы должны симулировать только его и не подменять его например на HEAD. Основная разница между данными методами в том, что GET получает содержимое ответа, а HEAD нет. Казалось бы зачем мне получать не нужные данные например от картинок, css, шрифтов, но как показывает практика они не менее важны.

Сравним два типа запросов для одного и того же тестового ресурса
HEAD

image

GET

image

На картинках видно, что GET запрос выполняется во много раз дольше, чем HEAD. А следовательно сервер дольше отдавал данные на данный запрос и не мог обслуживать следующие. При одном пользователе эта разница не кажется существенной, но при использовании 1 000 виртуальных пользователей сервер будет тратить времени больше не обработку каждого из них.

Например, наш Web-сервер настроен таким образом, что может обрабатывать только 100 одновременных подключений. В результате мы увидим, что первые 100 подключаться и будут работать как минимум 3 секунды. При этом все остальные 900 будут ждать возможности подключения. Как только кто-то из первой сотни закончит, то отдаст ресурсы следующему. То есть тысячный пользователь в нашем пример сможет начать работать с указанным запросом только примерно через 27 секунд. Если бы мы использовали HEAD метод, то тысячный пользователь получил бы доступ к системе уже через 2 секунды. (данные расчёты крайне грубые)

В результате мы видим, как использование «правильного» метода для обращения к серверу показывает реальную на него нагрузку.

Использованный на картинках пример является полностью синтетическим для отображения большей наглядности по времени выполнения запросов. У вас может не быть столь больших запросов. Но даже при ответе в 100 — 200 Килобайт и использовании 5 000 пользователей мы можем наблюдать значительные замедления в работе Web-сервера.

Проверка получаемых данных


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

Я сталкивался с ситуациями когда web-система сообщала об успешности выполнения запроса, отправляя ответ 200 ОК. Но тело запроса было пустым, после глубокого изучения системы удалось выяснить, что это запланированный ответ. То есть успешность выполнения запроса можно было только определить по наличию содержимого в ответе.

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

Сегодня, при интенсивном развитии технологий динамической работы с web-системами (AJAX, WebSocket, Flash, Java и др.), мы можем на один и тот же запрос получать различное содержимое. И необходимо быть уверенным, что текст ответа является правильным.

Построение «правильных» регулярных выражений


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

В сети интернет очень много примеров и статей на тему низкой производительности тех или иных регулярных выражений или движков, на которых они используются. В них рассказывается, что такое ленивые, жадные и сверх жадные квантификаторы. Почему и когда надо использовать группировки и чередования. Как выполнять конкретизацию для увеличения скорости работы движка регулярных выражений. Я думаю, кому это важно и интересно, смогут найти информацию.

Я же хочу продемонстрировать почему надо их выстраивать правильно. Возьмем некую последовтельность запросов, которые при записи имели некие задержки.

image

На картинке задержки обозначены зелеными стрелками. При выполнении сценария, утилита должна симулировать задержки между запросами тем самым гарантируя «реальную» нагрузку пользователя.

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

Выполняемые проверки должны тратить время на поиск данных. В результате мы получим примерно следующее

image

Красными стрелками показано какое-то время, которое будет затрачено на работу регулярных выражений.

В результате мы видим, что общее время выполнения сценария уже немного отклонилось о того, как если бы это делал один пользователь. Если же учесть, что каждый виртуальный пользователь должен делать такую проверку, а у нас на одном компьютере запущено 1 000 таких, то время на их обработку увеличится в несколько раз. Каждый виртуальный пользователь будет захватывать ресурсы операционной системы для проведения вычислений. Следовательно, пока ресурсы заняты одними пользователями, другие не могут получить к ним доступ.

Чем точнее у нас регулярное выражение, тем меньше времени тратится на его обработку, а мы получаем более реальную нагрузку на систему при большом количестве виртуальных пользователей

Конечно для многих использование регулярных выражений, а тем более их «правильного» варианта не требуется. Но если вы хотите приблизить свой тест к более реальным условиям выполнения виртуальными пользователями, то необходимо не забывать про скорость работы сервисных функций.

Заключение


Мы рассмотрели три возможных варианта, которые могут влиять на искажение результатов нагрузочного тестирования. Конечно не все из описанных ситуаций повлияют на такие параметры как время соединения с сервером, время ответа сервера и другие получаемые вами характеристики.

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

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

Update: завершаем подготовку в статье
Tags:
Hubs:
Total votes 7: ↑5 and ↓2 +3
Views 6.4K
Comments 0
Comments Leave a comment

Stories