В данной статье мы поделимся собственным практическим опытом, который мы приобрели при тестировании Web Apps приложения (интернет-магазина), работающего в облаке MS Azure, а также опишем, какими инструментами мы пользовались для решения этой задачи и о выводах, которые были сделаны по полученным результатам.
Объект тестирования
В качестве объектов тестирования мы выбрали VirtoCommerce Storefront (web приложение, использующееся в качестве front end'a приложений, создаваемых на платформе VirtoCommerce).
Для получения реальной картины возможностей системы нам необходимо смоделировать запросы пользователей максимально приближенно к реальности. Нет смысла проверять главную страницу, которая может находиться в кэше и потом утверждать, что наша скорость составила 1k req/sec. Толку от такой метрики производительности в реальной жизни нет.
Поэтому для того, чтобы наши результаты тестирования были статистически значимы и максимально близко отражали показатели производительности на реальном трафике, было принято решение использовать запросы, максимально приближенные к реальному поведению пользователя в интернет-магазине.
Остановимся на следующих действиях, из которых будет состоять наш «реальный» тест:
Действие пользователя (тип теста)
|
Удельный процент от общего количества запросов
|
Просмотр уникальной страницы категории с ее продуктами
|
30%
|
Просмотр уникальной карточки продукта
|
40%
|
Добавления товара в корзину
|
10%
|
Поиск товаров по уникальной ключевой фразе либо атрибуту
|
20%
|
Рис. 1. Основные действия пользователей и их удельная частота использования.
Подготовка тестовых данных
Наиболее важная фаза для любого тестирования — это подготовка данных. Тестовые данные должны быть подобраны таким образом, чтобы как можно более полно соответствовать данным в реальной системе, как по количеству, так и по качеству (связи, структура и пр). По возможности общее количество данных должно быть достаточно для того, чтобы при тестировании как можно меньше было повторных обращений к одинаковым данным, что позволит избежать частого использования кэша и в результате получить самую пессимистичную картину производительности системы.
Основными данными для интернет-магазина, как правило, являются: каталог продуктов и категорий с ценами, скидки и сведения об остатках.
В качестве наполнения тестируемой среды использовались реальные данные каталога, которые будут использоваться на основной production-среде:
Рис.2. Данные, используемые для наполнения тестируемой системы.
Понятно, что для читателя, не знакомого со структурой каталога VirtoCommerce, некоторые типы данных могут ничего не значить, но тем не менее приведем их для того, чтобы хотя бы иметь представление о количественном порядке.
Подготовка проекта и запись тестов
В качестве основного инструмента для нагрузочного тестирования мы будем использовать MS Visual Studio Enterprise 2017 ( в других редакциях студии поддержка данного типа проектов может отсутствовать) и тип проекта Web Performance and Load Test Project.
Рис.3. Создание нового проекта.
После создания проекта нам необходимо будет создать тесты для каждого из ранее определенных пользовательский действий. Ограничимся созданием теста для одного пользовательского действия в качестве примера, поскольку остальные действия создаются по аналогии.
Для тестов мы будем использовать стандартный тип теста Web Performance Test, встроенный в Visual Studio.
Нашим первым тестом, который мы создадим, будет тест, открывающий детали продукта в интернет-магазине.
Для создания теста выберем из списка предложенных Studio тип теста “Web Performance Test», зададим имя “Storefront-ProductDetail “.
Рис.4. Выбор типа теста в Visual Studio.
Для данного типа теста Visual Studio сразу же попытается открыть браузер, где можно будет в интерактивном режиме прокликать необходимые действия непосредственно на сайте, но мы этого делать не будем, но сразу закроем браузер и остановим запись. В итоге мы получим пустой тест Storefront-ProductDetail.webtest.
Далее нам нужно добавить источник данных для данного теста, для того чтобы можно было использовать различные параметры запроса в рамках одного теста, для этого в VS Studio Web Performance Test предусмотрена такая возможность.
В качестве источника данных для нашего теста мы будем использовать таблицу в базе данных, где хранятся записи о продуктах. После этого у нас появится возможность использовать данные из подключенного источника в запросе, который должен открывать детали продукта на тестируемом приложении. Достигается это путем вставки конструкции “{{Имя источника данных.Название таблицы.Название колонки}}”
В итоге после всех манипуляций наш первый тест примет вот такой вид.
Рис. 5. Содержимое теста
Настало время для первого запуска, попытаемся запустить наш тест и убедиться, что он работает корректно.
Рис. 6. Результат работы единичного теста
По аналогии создадим тесты для все остальных наших сценариев.
Рис. 7. Результирующий набор тестов
После этого у нас практически все готово к созданию комбинированного теста, который будет эмулировать реальное поведение пользователя на сайте.
Для этого добавляем в наш проект новый LoadTest
Рис.8. Создание нового load-теста
В появившемся мастере выбираем тип On-premises Load test.
Рис. 9. Выбор типа теста
Этот пункт требует определённого разъяснения, ведь вы справедливо спросите: «Причем тут on-premise?» Тема статьи о тестировании с помощью Teams Services и MS Azure, но тут есть нюанс, так как мы для тестов используем источники данных в виде таблиц или других внешних сервисов, то с этим могут возникнуть определенные сложности, когда мы попытаемся запустить данный тест в облаке.
После тщетных попыток заставить работать такие тесты в облаке мы отказались от этой затеи и решили использовать для тестирования так называемые «записанные» тесты, которые получаются путем записи запросов, генерируемых тестами работающих локально и имеющих подключение к источникам данных.
Для записи тестов мы используем Fiddler, у которого есть возможность экспорта запросов в формат Visual Studio Web Tests. Немного далее мы расскажем более подробно про процедуру записи такого теста.
На последующих шагах выбираем продолжительность тестирования, количество пользователей и, самое главное — указываем, из каких тестов будет состоять наш MixedLoadTest и в каких пропорциях они будут использоваться.
Рис.10. Составляющие теста
В результате после всех действий мы получим комбинированный MixedLoadTest, настроенный для запуска для локально-развернутого приложения.
Далее нам необходимо запустить данный тест и попытаться записать с помощью Fiddler все запросы которые будут генерироваться в результате работы теста, а также получить “запись”, которую мы сможем запустить уже непосредственно в облаке.
Предварительно запускаем Fiddler и наш MixedLoadTest тест.
Рис. 11. Результат работы теста
После отработки всех данных получим вот такую картинку в Fiddler
Рис. 12. Сессия теста в Fiddler
Далее в Fiddler сохраняем все сессии в формате Visual Studio Web Tests, File -> Export sessions -> All sessions -> Visual Studio Web Tests и добавляем полученный файл в проект. Напомню, что данное действие необходимо для того, чтобы мы смогли получить тест без привязки к внешним источникам данных, так как с запуском такого рода тестов могут возникнуть проблемы в облачной среде.
Рис. 13. Детали «записанного» теста
Теперь практически все готово для запуска нашего теста в облаке, последним шагом по подготовке теста нужно в любом текстовом редакторе открыть “записанный” MixedLoadTest и заменить в нем localhost:8888 (адрес прокси, Fiddler-а) на адрес нашего магазина в облаке.
Запуск теста в облаке
Для запуска тестов в облаке нам потребуется действующая учетная запись в Visual Studio Team Services.
Создаем новый LoadTest, только на этот раз выбираем Cloud-based Load Test with Visual Studio Team Services.
На следующих шагах выбираем дата-центр, с которого будет генерироваться трафик на тестируемый ресурс, а также максимальное количество агентов (пользователей) для константного паттерна, либо, если мы хотим использовать постепенное увеличение нагрузки, то необходимо задать соответствующие параметры.
На шаге выбора тестов, выбираем единственный тест, который мы записали ранее с помощью Fiddler, он и будет эмулировать «реальную» нагрузку на тестируемый ресурс.
После завершения создания запускаем тест, в процессе выполнения которого студия будет показывать некоторые ключевые метрики, такие как производительность и полоса пропускания, а также строить графики в реальном времени.
Рис. 14. Процесс работы теста в облаке
После завершения теста также можно посмотреть сохраненный веб отчет в VSTS:
Рис. 15. Web отчет на Visual Studio Team Services портале
Анализ результатов
Самый важный момент — это обработка и анализ полученных результатов теста. Для рассматриваемой задачи требовалось оценить производительность приложения, работающего на различных конфигурация Azure Web Apps B2 и B3 тарифах.
Для этого мы запускали “записанный” тест повторно для приложения на разных конфигурациях и фиксировали полученные результаты в Excel документе.
В итоге получился вот такой отчет:
Рис.16. Результирующий отчет тестирования
Проанализировав полученные данные, удалось выяснить предельную нагрузку которое может выдержать наше приложение — она составляет около 60 одновременных пользователей или 9 запросов/сек. при среднем времени отдачи страницы 2.5 сек. На графике видно, что проблемы с производительностью начинаются резко после определённого порогового значения количества запросов.
Как позже выяснилось, причиной тому являлась 100% нагрузка на процессор, из-за того, что мы использовали стороннюю библиотеку для серверного рендеринга страниц, которая использовала регулярные выражения для токенизации и разбора разметки.
Выводы
Производительность активно развивающегося приложения всегда имеет очень сильную склонность к деградации, ведь любое, даже самое незначительное с точки зрения разработчика изменение, может привести к драматическим последствиям для производительности приложения. В этой связи периодическое тестирование производительности — важная процедура, которая должна проводиться регулярно и быть частью Continuous Integrations процессов.
Сам проект и отчеты полученные в результате тестирования доступны на GitHub.
Автор: VirtoCommerce