...

пятница, 29 ноября 2013 г.

Яндекс.Танк и автоматизация нагрузочного тестирования

В ходе тестирования некоторых продуктов компании Positive Technologies возникла необходимость проведения быстрых стресс-тестов одного веб-сервиса. Эти тесты должны были быть простыми и быстрыми в разработке, нетребовательными к аппаратным ресурсам и одновременно с этим давать значительную нагрузку однотипными HTTP-запросами, а также предоставлять статистические данные для анализа системы под нагрузкой.

Для их реализации мы исследовали и опробовали некоторое количество инструментов, среди которых были Apache JMeter и написанный нами на Python скрипт LogSniper, который выполнял реплей заранее подготовленных серверных логов с HTTP-запросами на цель.


От использования JMeter было решено отказаться из-за значительной сложности подготовки и проведения тестов, высоких требований к производительности нагрузочного стенда и довольно малых мощностей нагрузки, хотя эти недостатки и компенсировались высокой информативностью собираемой статистики. LogSniper был отклонен из-за малой мощности генерируемой нагрузки и здесь даже простота подготовки нагрузочных HTTP-пакетов не смогла перевесить. Другие известные инструменты нам по тем или иным причинам тоже не подошли.


В итоге мы остановились на инструменте Яндекс.Танк, о котором узнали, побывав на конференции YAC-2013 и пообщавшись со специалистами Яндекса. Этот инструмент полностью отвечал всем нашим требованиям к простоте подготовки теста и к генерируемой нагрузке.


Что это




Яндекс.Танк — инструмент для проведения нагрузочного тестирования, разрабатываемый в компании Яндекс и распространяемый по лицензии LGPL. В основе инструмента лежит высокопроизводительный асинхронный генератор нагрузки phantom: он был переделан из одноименного веб-сервера, который «научили» работать в режиме клиента. При помощи phantom можно генерировать десятки и сотни тысяч HTTP-запросов в секунду (http-requests per second, http-rps).

В процессе своей работы Танк сохраняет полученные результаты в обычных текстовых журналах, сгруппированных по директориям для отдельных тестов. Во время теста специальный модуль организует вывод результатов в консольный интерфейс в виде таблиц. Одновременно запускается локальный веб-сервер, позволяющий видеть те же самые результаты на информативных графиках. По окончании теста возможно автоматическое сохранение результатов на сервисе Loadosophia.org. Также имеется модуль загрузки результатов в хранилище Graphite.


Некоторые полезные ссылки:




Сегодня мы не будем подробно останавливаться на установке и настройке Танка, поскольку эту информацию легко найти в сети, а сразу перейдем к описанию своего опыта его использования.

Сравнение производительности двух аналогичных веб-сервисов




В ходе работы нам потребовалось сравнить характеристики двух веб-сервисов, работу которых можно примерно описать как «прозрачные HTTP-прокси, перенаправляющие входящие запросы на backend-приложение».

Общую схему работы можно изобразить следующим образом:


image


На стенде с Танком использовался генератор нагрузки phantom с включенным монитором производительности.


В качестве стенда web-proxy на схеме использовались два тестируемых веб-сервиса, с которых при помощи агента Танка снимались показатели производительности. Условно назовем их Эталонный веб-сервис и Испытуемый веб-сервис. Нам требовалось понять, соответствует ли производительность испытуемого веб-сервиса эталонному.


Для backend использовалось небольшое веб-приложение, запущенное под Nginx и возвращающее одну простую HTML-страничку.


Выявленные ограничения




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

Характеристики стенда backend-приложения:



  • 8 vCPU, 4 GB, 10 Gb/s,

  • веб-сервер Nginx.




Максимальная отдача сервера, которой удалось добиться, составила ~ 25 000 http-rps, но и при нагрузке выше 25k http-rps работа стенда не была нарушена.

Стенд Танка с характеристиками 16 vCPU, 8 GB, 10 Gb/s позволил реализовать нагрузку до 300 000 http-rps.


Пропускная способность виртуальной среды ESXi, определенная с помощью Iperf, составила 8 Gb/s в одну сторону, 4 Gb/s при двухсторонней нагрузке между двумя виртуальными машинами.


Метрики и критерии сравнения




Перед началом работы для дальнейшего измерения мы определили следующие метрики каждого профиля нагрузки:

  • http_rps_out — значение http-rps, отправляемое с Танка на веб-приложение,

  • http_rps_in — значение http-rps, принимаемое на Танке со стороны веб-приложения,

  • http_request_size — размер http-запроса в байтах,

  • send_requests — количество отправленных HTTP-запросов,

  • bs_out — bytes per seconds, байт в секунду — параметр определяет скорость отправки данных с Танка,

  • bs_in — значение bs, отправляемое с веб-приложения в сторону Танка,

  • test_time — время теста в секундах,

  • response_time_med — среднее время, в которое укладывается 90% всех ответов.




Зная число HTTP-запросов и их размер, получаем, что bs и http-rps связаны по формуле: bs = http_rps * http_request_size.

В данном случае мы решили выбрать следующие критерии для сравнения работы веб-сервисов под нагрузкой:



  1. За все время теста значение параметра «время, в которое укладывается 90% ответов» у испытуемого веб-сервиса должно быть не больше, чем у эталонного веб-сервиса.

  2. На отрезке возрастания нагрузки на очередные 1000 http-rps значение параметра «время, в которое укладывается 90% ответов» у испытуемого веб-сервиса должно быть не больше, чем у эталонного веб-сервиса.

  3. За все время теста общее количество правильно обработанных запросов у испытуемого веб-сервиса должно быть не меньше, чем у эталонного веб-сервиса.




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

Тестовые HTTP-запросы




Для одного из профилей нагрузочных тестов нам требовалось создать смешанный HTTP-трафик из GET- и POST-запросов с линейным возрастанием нагрузки до 10k http-rps в течение 10 минут.
HTTP-запросы, вошедшие в патрон Яндекс.Танка


GET /loadtest/index.php?id=1&login=user&pwd=password HTTP/1.1
X-Sniffer-Forwarded-For: yandex-tank-example-domain.ptsecurity.ru
Host: backend-example-domain.ptsecurity.ru
User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

POST /loadtest/index.php HTTP/1.1
X-Sniffer-Forwarded-For: yandex-tank-example-domain.ptsecurity.ru
Host: backend-example-domain.ptsecurity.ru
User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Content-Length: 32

id=1&login=user&pwd=password


POST /loadtest/index.php HTTP/1.1
X-Sniffer-Forwarded-For: yandex-tank-example-domain.ptsecurity.ru
Content-Type: multipart/form-data; boundary=validFile
Host: backend-example-domain.ptsecurity.ru
User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Content-Length: 150

--validFile
Content-Disposition: form-data; name="login"; filename="validFile.txt"
Content-Type: text/plain

Valid file content
--validFile--






Чтобы упростить подготовку патрона для такого смешанного трафика, мы сделали скрипты, аналогичные perl-скриптам, предлагаемым на форуме.

Сбор данных и анализ результатов




После подготовки запросов мы просто запустили Танк стандартным образом и выполнили нагрузочный тест со смешанным трафиком для обоих тестируемых веб-сервисов.
Результаты для эталонного веб-сервиса



Информация веб-монитора Танка:

image


Информация консоли Танка:


image


Результаты для испытуемого веб-сервиса



Информация веб-монитора Танка:

image


Информация консоли Танка:


image


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



  1. Испытуемый сервис удовлетворяет первому критерию, так как для 90% запросов среднее время ответов для испытуемого сервиса не превышало такой же показатель для эталонного сервиса.

  2. Требование второго критерия выполнялось для каждого этапа нагрузки.

  3. Судя по анализу статус-кодов ответов, записанных в журналы Танка, испытуемый веб-сервис принял и корректно обработал запросов больше, чем эталонный веб-сервис.




Выводы




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

Кроме того, он хорошо внедряется в имеющиеся системы автоматизации. Например, для упрощения работы со стендом Танка — управления, запуска, подготовки патронов для лент, контроля за процессом тестирования и сбором результатов — мы без особых усилий написали класс-обвязку на Python, который подключается к стенду по SSH и выполняет все перечисленные действия. Затем этот класс был встроен в нашу существующую систему авто-тестирования.


Дополнительно вы можете посмотреть, как подключить и использовать высокопроизводительную систему Graphit для анализа большого числа графиков (о ней рассказывалось в одной из презентаций на конференции YAC-2013). Ее также можно приспособить для нужд нагрузочного тестирования с использованием Яндекс.Танка.


Выражаю благодарность моему коллеге Олегу Каштанову за техническую поддержку.


Автор: Тимур Гильмуллин (блог).


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.


Комментариев нет:

Отправить комментарий