#

Нагрузочное тестирование: что? где? когда?

Блог
После весны 2020 года слово “тестирование” приобрело некоторые неожиданные значения и неоднозначные коннотации — пожалуй, везде, кроме IT. В нашей сфере без него никуда — и так было всегда.

Видов тестирования ПО — множество: модульное, функциональное, А/В-тестирование, интеграционное, нагрузочное и т д. И на наш взгляд, как раз последнее является как самым важным, так и наиболее сложным. Ведь если ошибки, которые могут быть выявлены с помощью A/B-тестов, модульных, функциональных и интеграционных тестов, проявляются практически сразу после “выкатки” новой версии приложения, то проблемы, на выявление которых нацелено нагрузочное тестирование, — “спящие”. И обнаруживаются они только тогда, когда на новую версию вашего сайта или приложения придет реальный пользовательский трафик, с которым не справится “софтверная” часть проекта (база данных, application-сервер) или “железно-инфраструктурная” (нехватка оперативной памяти в кластере, большая нагрузка на дисковую подсистему при операциях чтения-записи).

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

Что? Где? Когда?

Когда необходимо:

Что включено:


Где смотреть:

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

Сценарии тестирования и выбор инструментов

Сценарии

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

Когда мы проводили нагрузочное тестирование для “Тотального диктанта”, в сценариях описывали следующие процессы:


Самые частые в нашей практики варианты формирования конечного сценария таковы:


Инструменты

Наши ТОП-2 — это Яндекс.Танк и Apache JMeter.


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

На наш взгляд, довольно простой и легкий инструмент для “простых” нагрузочных тестирований: переходы по страницам, без авторизации и прочих дополнительных условий. “Из коробки” позволяет строить графики по результатам нагрузки и предоставлять полноценный отчет о тестировании.


Пример конфигурационного файла для "Яндекс.Танка":

# cat load.yaml 

phantom:

  address: xx.yyy.zzz.qqq:443

  ssl: true

  load_profile:

    load_type: rps # schedule load by defining requests per second

    schedule: const(350, 1000s)

  header_http: '1.1'

  headers: 

     - "Host: test.ru"

     - "Connection: close"

     - "Accept-Encoding: gzip, deflate"

     - "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"

  ammofile: ./test.log_clear

  ammo_type: uri

  package: yandextank.plugins.Phantom

telegraf:

  enabled: false # let's disable telegraf monitoring for this time

overload:

  package: yandextank.plugins.DataUploader

  enabled: true

  token_file: ./token.txt

  api_address: https://overload.yandex.net/

  job_name: test.ru


Пример файла со списком url для конфигурационного файла из примера выше:

# head -n 10 test.log_clear

 

/stat/word/collect/c9cdc1dc-884f-45d3-b5d2-15e35cd1c7e8

/posts/78053

/books/10_non_fiction_knig_ot_noama_khomskogo-912394.xhtml

/world/samye_opasnye_v_mire_morya_8_faktov_o_piratakh_yugo_vostochnoy_azii-1161411.xhtml

/posts/92382

/posts/72761

/signin

/comments/58717

/comments/92382

/comments/92374

 

Пример графиков, генерируемых "Яндекс.Танком" в процессе тестирования 👆🏻

 

Apache JMeter — инструмент для проведения нагрузочного тестирования, разрабатываемый Apache Software Foundation. Хотя изначально JMeter разрабатывался как средство тестирования web-приложений, в настоящее время он способен проводить нагрузочные тесты для JDBC-соединений, FTP, LDAP, SOAP, JMS, POP3, IMAP, HTTP и TCP. Интересна возможность создания большого количества запросов с помощью нескольких компьютеров при управлении этим процессом с одного из них. Архитектура поддерживает плагины сторонних разработчиков, что позволяет дополнять инструмент новыми функциями.

Более тяжеловесный и требовательный к ресурсам инструмент, но обладающий и более широкой функциональностью: позволяет добавлять в http-запросы куки, заголовки (например, для авторизации), парсить страницы для получения значения тех или иных переменных и использования их в последующих запросах; в конечном итоге, даёт возможность полностью эмулировать работу браузера. Мы используем JMeter тремя способами:

Из минусов — нет встроенных графиков, приходится дополнительно конфигурировать связку с Grafana (что, впрочем, делается довольно легко). Из плюсов — большое комьюнити + большое количество плагинов для тестирования чего угодно (в нашей бигдата платформе мы используем JMeter для генерирования потоковых данных для Apache Kafka и дальнейшей обработки через Apache Spark)

Пример конфигурации JMeter для процесса залогинивания.

Пример конфигурации JMeter для увеличения RPS 👆🏻

 

Примеры графиков/таблиц из настроенной Grafana для Jmeter 👆🏻

Само тестирование и отчёты

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

В результате нагрузочного тестирования на выходе мы получаем набор графиков — зависимости времени ответа страницы от RPS входящей нагрузки и утилизации ресурсов в зависимости от RPS, — исходя из которых в финальном отчете мы показываем как текущие возможности/лимиты системы, так и рекомендации по увеличению производительности проекта. Эти рекомендации могут относиться уровню инфраструктуры (отсутствие механизмов автомасштабирования, проблемы на уровне сети) и к уровню архитектуры и кодовой базы (неоптимизированные SQL-запросы, отсутствие индексов в БД, устаревшее ядро bitrix; неоптимальное распределение операций чтения/записи между master/slave БД).

Пример из отчета с рекомендациями по оптимизации SQL-запросов 👆🏻

 

Примеры с рекомендациями по результатам нагрузочного тестирования 👆🏻

 

Интересный пример из практики: клиенту нужна была дополнительная образовательная система для обучения сотрудников, проводили нагрузочное тестирование обеих 👆🏻
 

В чём польза, брат?

Как и любые профилактические проверки, периодическое нагрузочное тестирование будет, несомненно, позитивно влиять на развитие вашего продукта/сервиса. В идеальном мире, при наличии stage(preprod)-площадки, идентичной продакшну, нагрузочное тестирование можно встраивать непосредственно в процессы CI/CD при выкладке новой версии проекта на препродакшн.

Кроме того, оно помогает выявить ошибки как в архитектуре проекта, так и в его кодовой базе. В нашей практике был интересный пример, когда stage-проект, развернутый в managed-кластере K8s, выдерживал всего лишь 8 RPS, а потом падал вплоть дорестартов всех pod’ов деплоймента. После трех итераций нагрузочного тестирования (с разницей в неделю) производительность выросла до 110 RPS.

Резюмируя: в отличие от различных других тестирований (и не только в IT — см. начало статьи), нагрузочное тестирование — это не просто констатация, “болен” пациент или нет, это тотальное и исчерпывающее исследование проекта на предмет узких мест, которые могут стать причиной отказа сайта или сервиса при росте нагрузки. И, в нашем случае, — ещё и дорожная карта по устранению проблем.

Так что берегите здоровье проекта и не забывайте вовремя его проверять!

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