Как стать автором
Обновить

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

Время на прочтение13 мин
Количество просмотров4.3K

Вступление

В данной статье хочу рассказать про сервис load-testing-hub, главная задача которого это сбор, агрегация, анализ и визуализация данных о нагрузочном тестировании

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

Рассмотрим основные возможности load-testing-hub, такие как создание наглядных графиков и отчетов, подробное сравнение результатов нагрузочных тестов

Перед тем, как начать рассказ о сервисе хотелось бы обозначить проблему/ошибку, которую я часто встречал и сам допускал при проведении нагрузочного тестирования. Зачастую в компаниях нагрузочное тестирование происходит примерно так: находится коллега, который либо уже имел опыт нагрузочного тестирования, либо не против в этом разобраться, пусть коллегу зовут Иван. Иван выбирает инструмент, подготавливает окружение, возможно при подготовке окружения руководствуется поддержкой команды разработки, либо в качестве окружения выбирает один из уже существующих стендов. Хорошо, если у Ивана есть какие-то SLA требования к системе, которую он будет нагружать, зачастую этого тоже нет. И вот у Ивана есть какой-то инструмент, какой-то стенд для нагрузочного тестирования, какие-то SLA, Иван предупредил коллег, что сейчас стенд будет переживать не лучшие времена, потому что Иван планирует запустить на нем нагрузочные тесты. Настал день X запускается нагрузочное тестирование, в качестве артефакта Иван получил метрики, которые сгенерировал инструмент нагрузочного тестирования. И что дальше? Обычно ответ такой: "Ну вроде система держит/не держит". На этом процесс нагрузочного тестирования, как правило, заканчивается, если обнаружились какие-то очевидные проблемы, то их уже расследует команда разработки. Метрики и результаты нагрузочного тестирования никак не обрабатываются, обычно, публикуется какой-нибудь HTML отчет на github/gitlab pages, отправляется уведомление в рабочий чатик, возможно более продвинутые коллеги закидывают отчеты на S3, менее продвинутые коллеги заполняют руками XLSX/google sheets или другие таблицы

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

В чем проблема подхода выше? Ведь Ивану удалось обнаружить потенциальные проблемы, либо же убедиться, что система держит нагрузку и все хорошо. Данный подход работал бы, если бы продукт/система и все вокруг него находилось бы в абсолютной стагнации. На практике никогда так не происходит, все быстро развивается, с каждым новым релизом в систему добавляется больше фичей, обновляются зависимости, меняются фреймворки, библиотеки, добавляются миграции, добавляются новые контракты, меняется бизнес логика и т.д., все эти изменения могут привнести в систему ухудшение производительности по отношению к другим версиям. Напрашивается автоматизация данного процесса, нужны регулярные запуски НТ, нужен единый центр агрегации и анализа результатов НТ, чтобы иметь возможность принимать решения о релизе продукта перед каждой новой версией/фичей. В этой статье, я хотел бы рассказать про сервис load-testing-hub, который закрывает проблему анализа результатов НТ. К идее создания данного сервиса я пришел интуитивно и спустя огромное количество практики, все описанное в статье имеет практическое применение и закрывает реальные бизнес задачи. Что касаемо процесса автоматизации НТ, то не буду подробно останавливаться на нем - это тема для отдельной статьи, дам лишь краткое описание

Предыстория

Идея о создании сервиса load-testing-hub пришла после долгого анализа и рассуждения на тему агрегации артефактов нагрузочного тестирования. Хотелось иметь сервис, который будет автоматически анализировать результаты нагрузочного тестирования и сравнивать их с фактическими результатами и с SLA. Также хотелось иметь единый центр агрегации всей информации о НТ, чтобы можно было отслеживать статистику/аналитику/динамику показателей RPS, среднего времени ответа, количества запросов, за длительный промежуток времени

Рассмотрим процесс автоматизации нагрузочного тестирования, про который говорилось выше:

  • Выходит новая версия сервиса - создается новый тэг в gitlab и запускается пайплайн, созданный тэг раскатывается на нагрузочное окружение. Нагрузочное окружение представляет собой нагружаемый микро сервис, у которого все внешние зависимости замоканы. У нагружаемого сервиса своя база данных, заранее заполненная огромным количеством данных, в рамках нагрузочного сценария готовятся данные только для самого сценария;

  • После раскатки созданного тэга на нагрузочное окружение происходит триггер на пайплайн с нагрузочными тестами. В пайплайне с нагрузочными тестами в первую очередь готовятся данные, далее запускаются сами нагрузочные тесты и последним шагом идет отправка, публикация и анализ результатов. В качестве фреймворка для нагрузочного тестирования используется locust, но для загрузки результатов в сервис load-testing-hub в принципе может подойти любой другой фреймворк, все загружаемые данные стандартны и их умеет генерировать практически любой фреймворк для НТ;

  • И как раз следующим шагом необходимо было иметь сервис, который бы мог проанализировать результаты НТ и исходя из результатов анализа, мы могли бы принять решение о дальнейшем релизе сервиса на продакшн

Архитектура

Архитектура сервиса load-testing-hub предельно проста, но в тоже время используется современный стек технологий, что влияет на масштабируемость сервиса в будущем. Весь сервис load-testing-hub состоит из UI части написанной на typescript и API части написанной на python:

Settings

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

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

Ниже выбран только сервис

Выбран только сервис
Выбран только сервис

Ниже выбран и сервис и сценарий

Выбран сервис и сценарий
Выбран сервис и сценарий

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

  • user_service - очень критичный и должен держать нагрузку от 5000 виртуальных пользователей и 1000 RPS;

  • account_service - менее критичный и должен держать нагрузку от 1000 виртуальных пользователей и 250 RPS;

Соответственно оба этих модуля относятся к сервису users_service, но при этом к ним разные требования, это означает, что и аналитику по каждому из них нужно будет оценивать в индивидуальном порядке

Dashboard

На странице Dashboard отображается вся усредненная информация агрегируемая из всех результатов НТ. Давайте рассмотрим все по порядку

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

Average numbers
Average numbers

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

Сравнение с SLA
Сравнение с SLA

Далее идет несколько виджетов с графиками, которые отображают следующие показатели:

  • Total requests per second - количество запросов в секунду, каждый грид/столбик на графике это один запуск нагрузочных тестов соответственно, чем больше запусков нагрузочных тестов за определенный промежуток времени, тем больше гридов/столбиков на графике;

  • Total requests - общее количество запросов за один нагрузочный тест, разделение аналогично с предыдущим графиком;

  • Response times (ms) - график, который показывает время ответа: минимальное, максимальное и среднее, разделение аналогичное двум предыдущим графикам.

Total requests per second. Total requests
Total requests per second. Total requests
Total requests. Response times (ms)
Total requests. Response times (ms)

Следующие несколько графиков отображают средние значения за определенный промежуток времени, но уже с группировкой по методам/ручкам. В примере я использовал названия методов, как это принято в GRPC протоколе, например GetUser, но на самом деле это не принципиально, на их месте могут быть REST-вые эндпоинты, например, /api/v1/get-user или что либо другое. Аналогично предыдущим графикам есть фильтры, которые позволяют посмотреть аналитику за определенный промежуток времени

  • Average requests per second by method - средний RPS по каждому из методов;

  • Average number of requests by method - среднее количество запросов по каждому из методов;

  • Average response time by method (ms) - среднее время ответа по каждому из методов.

Average requests per second by method. Average number of requests by method
Average requests per second by method. Average number of requests by method
Average number of requests by method. Average response time by method (ms)
Average number of requests by method. Average response time by method (ms)

Страница Dashboard закрывает потребность в аналитике/анализе результатов НТ за любой промежуток времени, тут же можно отслеживать динамику результатов. Наглядно отображается сравнение средних показателей с заданными SLA

Results

На странице Results списком отображаются результаты НТ

Results
Results

На каждой карточке с результатами отображается краткая информация о запуске НТ:

  • Версия нагружаемого сервиса, как я описывал выше процесс НТ, при каждом новом тэге запускаются нагрузочные тесты;

  • Сравнение результата с предыдущими и средними значениями;

  • Общий RPS в ходе теста;

  • Количество виртуальных пользователей;

  • View details - открываются детали результата;

  • Open trigger pipeline - открывается ссылка на пайплайн, который триггернул нагрузочные тесты. Опционально;

  • Open load tests pipeline - открывается ссылка на пайплайн с нагрузочными тестами. Опционально;

  • Шкала на которой отображается количество запросов, зеленым отображается количество успешных запросов, если есть зафейленные запросы, то они будут отображаться красным;

  • Время начала и окончания запуска НТ.

Результаты можно фильтровать по дате, времени и по версии

Results filters
Results filters

По сути это вся краткая информация, которая позволяет бегло оценить результат НТ, для более подробной оценки посмотрим на страницу Result details

Load tests result details
Load tests result details

В самом начале на странице Result details отображается виджет, который показывает все общие показатели нагрузочного теста

Следующий виджет это таблица с более подробными показателями по каждому из нагружаемых методов

Methods results table
Methods results table

Следующие три виджета это графики:

  • Total requests per second - показывает динамику изменения количества запросов в секунду и количества ошибок в секунду;

  • Response times (ms) - показывает динамику изменения среднего времени ответа и 95-го перцентиля в миллисекундах;

  • Number of users - показывает динамику изменения количества виртуальных пользователей;

Total requests per second. Response times (ms)
Total requests per second. Response times (ms)
Response times (ms). Number of users
Response times (ms). Number of users

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

Вернемся на самый верх страницы Result details и посмотрим на функциональность тулбара

Result details toolbar
Result details toolbar

Начнем слева направо:

  • Сравнение текущего результата с предыдущим запуском и средними значениями. Сравнение текущего результата с SLA для сценария. Позже посмотрим более подробно, на каждый метод сравнения;

  • Возможность посмотреть логи в kibana для сервиса. Интеграция с kibana настраивается на уровне load-testing-hub-api;

  • Возможность посмотреть графики в grafana. Ссылка на dashboard в grafana формируется автоматически, в ссылку подставляется период запуска HT и на графиках в grafana можно уже наглядно видеть, как вел себя сервис в период нагрузки. Интеграция с grafana настраивается на уровне load-testing-hub-api;

  • Ссылки на предыдущий запуск и на пайплайны, которые мы уже видели на карточке результата на странице Results.

Теперь поговорим про сравнение результатов. Всего в сервисе load-testing-hub есть два вида сравнения:

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

  • Сравнение текущего результата с SLA. Тут все предельно просто, данный параметр показывает отклонение от заданных в сценарии SLA. Позже рассмотрим, как задаются SLA для сценария. Данный параметр статичен, в отличие от предыдущих и средних значений. Например, сервис начал деградировать и с каждым новым релизом среднее и предыдущие значения будут только ухудшаться, но SLA останутся теми же, что позволит нам объективно оценивать производительность

На странице Compare with actual data можно видеть сравнение значения RPS из текущего результата с предыдущим результатом и средним значением. Ниже есть статистика по каждому нагружаемых методов, что позволяет более детально разобрать какой из методов сильнее всего просадил производительность

Compare with actual data
Compare with actual data

На странице Compare with scenario SLA можно видеть сравнение значения RPS из текущего результата с заданными SLA для сценария. Наглядно видно, по какому из методов идет большее отклонение, что позволяет заранее увидеть аномалии в производительности, даже если общий показатель RPS в норме

Compare with scenario SLA
Compare with scenario SLA

По сути это все, что касается анализа результатов, есть еще разделы, как например Methods, который мы рассмотрим ниже, но раздел Results является самым показательным и основным. На основе результатов сравнения уже можно делать вывод о дальнейшем релизе новой версии сервиса. Лично для меня данной информации более чем достаточно, но возможно в зависимости от компании/команды требования к сервису аналитики/метрик НТ могут быть другие, я лишь показываю подход, к которому пришел спустя большое количество практики

Methods

Раздел Methods представляет собой аналитику по каждому из методов сервиса/сценария, которая автоматически агрегируется на основе всех результатов НТ. Данный раздел позволяет подробно оценить производительность каждого метода в определенный промежуток времени

Methods
Methods

На каждой карточке отображается краткая информация о методе:

  • Название метода, в данном примере это GRPC метод, но на его месте может быть, что угодно, в целом это определяется на уровне используемого фреймворка для НТ;

  • Средний RPS;

  • Среднее время ответа;

  • Протокол, в данном случае это GRPC;

  • Среднее количество успешных/зафейленных запросов;

Методы можно фильтровать по дате, времени и по названию метода

Methods filters
Methods filters

Более подробная информация отображается на странице Method details. Как и на странице Result details есть виджет с подробными показателями по методу, данные показатели агрегируются из всех результатов НТ. Конечно же можно выставить временной фильтр, чтобы оценить показатели, например, за последние пол года

Method details
Method details

Следующий виджет на странице показывает сравнение среднего RPS текущего метода с заданными SLA для сценария. Данный виджет показывается по аналогии с виджетом сравнения на странице Dashboard

Compare method with SLA
Compare method with SLA

Следующие три виджета Total requests per second, Total requests, Response times (ms) отображают графики аналогичные графикам на странице Dashboard, только в данном случае для построения графиков используются агрегированные данные по конкретному методу

Total requests per second. Total requests
Total requests per second. Total requests
Total requests. Response times (ms)
Total requests. Response times (ms)

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

Scenarios

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

Scenarios
Scenarios

Можно посмотреть детали сценария. Это та же информация, которая отображается в разделе Ratio на странице Result Details, только там данная информация показана для конкретного сценария НТ, на странице Scenarios можно посмотреть для любого сценария, выбранного сервиса

Scenario details
Scenario details

Также на странице Scenarios настраиваются SLA, для конкретного сценария. Можно прописать общий RPS для сценария, ниже можно прописать RPS для каждого метода. Методы автоматически агрегируются из результатов НТ и предлагаются для выбора

Scenario SLA
Scenario SLA

Загрузка результатов

Как уже говорил в начале, для проведения НТ использую python + locust, соответственно все результаты в сервис load-testing-hub формируются из артефактов locust-а. Locust это всего лишь инструмент, коих много и каждый инструмент умеет генерировать артефакты с основными метриками, такими, как RPS, общее количество запросов, максимальное время ответа, минимальное время ответа, среднее время ответа и т.д., на основе этих артефактов, можно загружать данные в сервис load-testing-hub. И даже если каких-то метрик в фреймворке нет, то думаю это не проблема сделать форк/pull request и доработать/добавить функциональность под свои требования. На крайний случай, можно сделать обертку для используемого фреймворка и собирать метрики самому, но еще раз повторюсь, это крайний случай. С locust-том также не обошлось без доработок, так как стандартного артефакта в виде json файла было недостаточно

Создал репозиторий load-tests-hub, где приведен пример, как можно загрузить результаты в сервис load-testing-hub, используя python и locust. Если кратко, то стандартного json отчета locust-а недостаточно, расширить отчет и получить доп инфу можно так

from locust import events
from locust.env import Environment
from reports.locust.controllers import dump_locust_report_stats

...

@events.test_stop.add_listener
def on_test_stop(environment: Environment, **kwargs):
    dump_locust_report_stats(environment)

Реализацию функции dump_locust_report_stats можно посмотреть тут, вся ее задача сводится к тому, чтобы собрать данные из объекта Environment, положить их в нужную структуру и сохранить в json файл stats.json , данный файл понадобится для отправки результатов в сервис load-testing-hub

Отправка результатов выглядит таким образом, в репозитории привел пример реализации на python, но можно сделать на любом другом языке, суть от этого не меняется

import asyncio

from reports.locust.controllers import get_locust_report_summary, get_locust_report_stats
from reports.metrics.client import get_load_testing_metrics_http_client
from reports.metrics.controllers import send_load_testing_metrics


async def main():
    stats = get_locust_report_stats()
    summary = get_locust_report_summary()

    load_testing_metrics_client = get_load_testing_metrics_http_client()

    await send_load_testing_metrics(load_testing_metrics_client, stats, summary)


if __name__ == '__main__':
    asyncio.run(main())

Заключение

Подведем итог всего описанного выше, load-testing-hub - это сервис, который собирает и централизует всю информацию о НТ. Мы получаем единый центр принятия решений, о производительности системы, который позволяет нам пользоваться следующим функционалом:

  • Отслеживать динамику производительности системы за любой промежуток времени;

  • Сравнивать результаты НТ c фактическими данными и с желаемыми SLA, на основе этих данных мы можем делать вывод о деградации и аномалиях в производительности сервиса. Также это позволяет выстраивать автоматический процесс НТ и принимать решение о релизе системы. Стоит отметить, что автоматический процесс НТ конечно же можно сделать и без использования сервиса load-testing-hub, но в таком случае я слабо представляю, как будет происходить анализ результатов, возможно в голове, либо по субъективному мнению кого-то из коллег, либо перебирать все отчеты за последний месяц;

  • Видеть подробную аналитику по каждому нагружаемому методу, на основе этого можно делать вывод о проблемах в конкретной части/модуле/методе/эндпоинте системы;

  • Задавать SLA для каждого сценария, далее система автоматически будет сравнивать текущие результаты с желаемыми SLA

Возможно перечислил не весь функционал сервиса load-testing-hub, но перечисленное мною имеет практическое применение и приносит пользу, экономя большое количество времени и помогая в принятии решений о релизе продукта

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

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

Исходный код сервиса load-testing-hub вы можете найти на моем GitHub:

Теги:
Хабы:
Всего голосов 8: ↑7 и ↓1+8
Комментарии11

Публикации

Истории

Работа

Ближайшие события

25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань