ru en

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

Содержание

  1. Нагрузочное тестирование

  2. Создаем систему организации нагрузочных тестов

  3. Установка и настройка

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

  5. Запускаем тестирование

  6. Вывод



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

Довольно часто, при развертывании или разработке ресурса или сервиса нам приходится решать такие вопросы как:

  • - Достаточно ли ресурсов у оборудования – хватает ли памяти, CPU и т.д. для обработки ожидаемой нагрузки на сервера
  • - Насколько быстро реагирует оборудование, комфортен ли пользовательский отклик?
  • - Эффективно ли работает разработанное приложение?

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

Очень часто архитектура разрабатываемого приложения, не вызывающая проблем во время разработки, перестает нормально функционировать, когда происходит «наплыв» пользователей со своим окружением. Приложение, работавшее на этапе разработки, с несколькими сотнями пользователей начинает работать с перебоями когда пользователей становится больше 10 тысяч.

Зачастую эта проблема возникает из-за сочетания 2-3 ошибок на этапе разработке: один из разработчиков, к примеру, написал некорректный алгоритм, другой – использовал неоптимизированный код. Безусловно, современное железо достаточно мощное и спокойно закрывает неоптимизированные моменты в разработке, что в целом особо не сказывается на производительности. Однако, при большом наплыве посетителей или большом объеме данных все эти незначительные ошибки «выстреливают» и делают сервис недоступным для работы.

Помимо этого, использование нагрузочного тестирования на уже готовом проекте может привести к дорогостоящей переделке всего приложения. Разработчики написали вполне рабочий код, но в процессе тестирования выясняется, что, согласно техническому заданию, необходимо обеспечить, к примеру, 10 ответов в секунду, а разработанное приложение может выдать только один, да и тот с большими задержками. Еще хуже, если на этапе проектирования был выбран неверный фреймворк (из-за популярности или скорости разработки) – тогда придется переделать вообще все приложение.

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

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

 

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

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

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

Основные плагины Яндекс.Танка:

1. Monitoring Plugin - плагин слежения за основными метриками тестируемого приложения

2. Phantom- генератор нагрузки c акцентом на высокую производительность, малое потребление ресурсов и точность выходных данных. На рисунке ниже приведена схема работы Phantom.

Основные параметры Phantom:

ammofile - путь к файлу патронов (файл патронов - это файл, содержащий запросы, которые должны быть отправлены на сервер. Может быть заархивирован).

load_profile - поведение профиля нагрузки.

rps_schedule - схема нагрузки. В ней можно указать одну из функций: const(load,dur), line(a,b,dur), step(a,b,step,dur), либо комбинации данных функций.

Например, комбинация:
rps_schedule=const(1,30s) line(1,1000,2m) const(1000,3h)
задаёт схему нагрузки при использовании которой нагрузка в 1 http-rps будет держаться в течении 30 секунд, затем нагрузка будет линейно возрастать с 1 до 1000 http-rps в течении 2 минут, после чего будет держаться на уровне 1000 http-rps в течение 3 часов.

step(a,b,step,dur) - пошаговое увеличение нагрузки, где a и b начальное и конечное значения нагрузки в http-rps, step - шаг увеличения нагрузки, dur - время, через которое увеличивается нагрузка на указанный шаг.

line(a,b,dur) - линейная нагрузка, где a и b - начальная и конечная нагрузка, dur - время, в течение которого нагрузка линейно увеличивается от a до b.

const(load,dur) - постоянная нагрузка, где load - значение нагрузки, dur - время нагрузки.

instances - максимальное количество экземпляров (параллельных запросов).

loop - количество повторений запросов из файла с патронами в цикле.

3. ConsolePlugin - отображение в консоли в реальном времени основных статистических данных.

4. Autostop - плагин, реализующий возможность возможность остановить тестирование на основе разных критериев.

5. Aggregator plugin -отвечает за накопление данных, полученных от различных типов модулей, и дальнейшую передачу накопленных данных в другие модули.

 

Установка и настройка Яндекс.Танка

В качестве ОС для развертывания танка мы используем Ubuntu. Сам процесс установки достаточно несложен:

1. Добавляем репозиторий танка в файл /etc/apt/soures.list

deb http://ppa.launchpad.net/yandex-load/main/ubuntu trusty main
deb-src http://ppa.launchpad.net/yandex-load/main/ubuntu trusty main

2. Далее выполняем в консоли следующие команды:

sudo apt-get install python-software-properties
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:yandex-load/main

3. И устанавливаем сам Яндекс.Танк

sudo apt-get update
sudo apt-get install yandex-tank

4.Итак, танк установлен. Однако для работы нам еще нужен phantom

sudo add-apt-repository ppa:yandex-load/main && sudo apt-get update
sudo apt-get install phantom phantom-ssl

5. Итак, все установлено. Осталось создать профиль нагрузки и можно будет стрелять из танка. Создаем файл load.ini с текстом:

[phantom]
address=example.com:80 ;
rps_schedule=const(65000,2m) ;
header_http = 1.1
headers = [Host: example.com]
[Connection: close]
ammofile=/root/ammo.txt #[//путь к файлу с патронами]
uris = /
[web]
port = 80
interval = 1
manualstop = 1

6. Формируем файл с патронами ammo.txt

Сам патрон состоит из:

пути для GET-запроса (uris).

хедера http-пакета.

Пример текста патронов приведен ниже:

GET /1aHttIs5nifm/IwrmPUP57DBtzQEH0/T5ON6sj0aiKS/YGlwMDCr2DdrC HTTP/1.1
Host: 10.11.1.100:8080
User-Agent: Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
Connection: close
X-Yatank-Tag: Normal_Requests

GET /RK9k9PiJffFdWt2we/CZbEh7d6s HTTP/1.1
Host: 10.11.1.100:8080
User-Agent: Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
Connection: close
X-Yatank-Tag: Normal_Requests

GET /Sq0UEAEit/SYRgBdKWeiWnxboI/YsFiuNXBWzBFg/HiGoY/ZfalGuvdVJrLKPJ6CpVoQ/0feikD3Py5 HTTP/1.1
Host: 10.11.1.100:8080
User-Agent: Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
Connection: close
X-Yatank-Tag: Normal_Requests

 

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

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

- 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.

 

Запускаем тестирование

Ниже на рисунке приведен жизненный цикл нагрузочного тестирования.

Итак, все установлено, конфигурационный файл создан, патроны заряжены, попробуем пострелять по тестовому серверу, на котором расположен тестовый сайт

Запускаем Yandex.Tank:

yandex.tank -c load.ini

Стреляем по серверу. Тест №1.

rps_schedule=const(1,30s) line(1,1000,2m) const(10000,5m)

Ответ от Танка.

График нагрузки на сервер

Вывод:

Отклик сайта при нагрузке 10 000 rps составила 3258 ms, что для нормальной работы сайта категорически неприемлемо.

Однако "железо" сервера вполне себе справляется с нагрузкой. На картинке видны ровные графики.

Уменьшаем нагрузку. Тест №2.

line(1,500,2m) const(5000,5m)

Ответ от Танка.

График нагрузки на сервер

Вывод:

Отклик сайта при нагрузке 5 000 rps составил 1251 ms, что показывает, что сайт достаточно хорошо справляется при такой нагрузке. Конечно цифры далеки от идеальных и все наш сайт необходимо подвергнуть анализу на предмет не оптимизированных участков кода.

Тест №3. Стресс-тест для сервера или минутка разрушения.

Из предыдущих тестов было видно, что при нагрузке 10 000 rps сервер прекрасно себя чувствовал. Установим нагрузку в 500 000 rps и посмотрим, как отработает наше железо.

line(1,500000,2m) const(500000,5m)

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

 

Вывод

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

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


Оставить заявку