![](https://habrastorage.org/getpro/habr/upload_files/23d/c4b/0ac/23dc4b0acced64b05cff30dc4ba89cc7.png)
На связи команда перфоманс-тестинга. Нам важно развитие профессиональных стандартов и профессионального комьюнити. В конце октября мы провели митап на тему нагрузочного тестирования. В статье расскажем про доклады спикеров и дадим ссылки на все материалы.
На митапе обсудили, как автоматизировать запуски тестирования производительности в Kubernetes с помощью GitLab CI и объяснили, почему нельзя просто взять и нагрузить Kubernetes. Затронули применение деструктивных тестов в рамках нагрузочного тестирования и разобрали деструктивное тестирование на примере одной из систем. В конце встречи провели круглый стол на тему «Тренды нагрузочного тестирования в 2023 году».
Автоматизация запуска тестирования производительности в Kubernetes
Сергей Данилов рассказал о предпосылках внедрения Kubernetes и нагрузочного тестирования в нем, разобрал путь от идеи до решения и проблем, с которыми столкнулись. А еще рассказал, как реализовали процесс в Gitlab CI в нашей команде.
![Стек технологий нагрузочного тестирования Стек технологий нагрузочного тестирования](https://habrastorage.org/getpro/habr/upload_files/cfa/977/e25/cfa977e2586cefba1d298ed937719bd5.png)
Предпосылки внедрения:
Сложности доставки аппаратных ресурсов в короткий срок и их оптимизация.
Решение вопросов масштабирования.
Унификация запуска нагрузочного тестирования после внедрения k8s. Можно использовать те же ресурсы и бонусы, что и ваше приложение от размещения в нем.
Все объекты k8s задаются с помощью конфигурационных файлов, которые описывают структуру сущности объектов:
Pod — минимальный абстрактный объект k8s, содержит в себе один или несколько контейнеров.
Service объединяет поды в группу и определяет доступ к ним.
Ingress описывает правила проксирования трафика от внешнего пользователя до сервисов внутри k8s.
![Пример работы приложения: есть внешний клиент и кластер k8s. Клиент отправляет трафик в Ingress, тот по своим правилам routing rule перенаправляет трафик в нужный сервис, у сервиса есть поды, которые ему отвечают. Подов может быть больше, два — минимальное количество для поддержки отказоустойчивости Пример работы приложения: есть внешний клиент и кластер k8s. Клиент отправляет трафик в Ingress, тот по своим правилам routing rule перенаправляет трафик в нужный сервис, у сервиса есть поды, которые ему отвечают. Подов может быть больше, два — минимальное количество для поддержки отказоустойчивости](https://habrastorage.org/getpro/habr/upload_files/c42/a5b/2f4/c42a5b2f4c4cbe7dda663f0a567723a8.png)
Чтобы протестировать нагрузку на сервис, нужно вместо клиента подставить какой-то инструмент, например Gatling. Потом сгенерировать пользовательский трафик, отправить его на Ingress. Если все работает — данные уходят в сервис, поды реагируют.
Выше описан пример простого тестового приложения, но если возьмем продовую среду — там все намного сложнее.
![За Ingress находится несколько сервисов, у них разное количество подов, все работает. Допустим, мы решили нагрузить Service1: отправляем нагрузку, Gatling генерирует трафик, отправляет его в Ingress, а тот передает все в Service1. Если в какой-то момент начнутся проблемы — увеличится время ответа, появятся ошибки и негативное влияние пойдет не только на Service1, но и на Service2 и на Service N, может случиться полная недоступность За Ingress находится несколько сервисов, у них разное количество подов, все работает. Допустим, мы решили нагрузить Service1: отправляем нагрузку, Gatling генерирует трафик, отправляет его в Ingress, а тот передает все в Service1. Если в какой-то момент начнутся проблемы — увеличится время ответа, появятся ошибки и негативное влияние пойдет не только на Service1, но и на Service2 и на Service N, может случиться полная недоступность](https://habrastorage.org/getpro/habr/upload_files/54e/1b9/532/54e1b95322ea130adf99d07acf551dae.png)
Чтобы избежать полной недоступности, мы решили отправлять трафик в обход Ingress, нагружать напрямую Service и запускать тесты внутри namespase.
Еще несколько полезных абстракций:
Deployment — описывает работающее приложение, манифест похож на предыдущие абстракции, но в нем описывается количество реплик.
Job — предназначен для выполнения разовых задач, например миграций или бэкапов.
ConfigMap — ресурс для хранения и внедрения конфигурации в контейнеры, можно передавать как Key value, так и списком параметры из файла.
![Процесс внедрения в запуск нагрузки Процесс внедрения в запуск нагрузки](https://habrastorage.org/getpro/habr/upload_files/9f1/308/611/9f1308611bf760fa9f55ca1feda99f68.png)
Проблемы, с которыми столкнулись при внедрении.
Проблема: сборка docker image — один docker image не подходит для более чем 150 проектов. Проекты и скрипты могут изменяться, и неясно, как это поддерживать.
Решение: собрать проект внутри docker image. Пакуем туда Gatling и различные утилиты, а сами скрипты нагрузочного тестирования копируем на этапе выполнения нагрузочного контейнера.
![Пример выполнения команды Пример выполнения команды](https://habrastorage.org/getpro/habr/upload_files/4e3/047/478/4e3047478d35f3fe8b4390144b41aa71.png)
Проблема: как деплоить и что выбрать в качестве сущности деплоя — deployment или job. Кроме того, могут существовать дополнительные требования по поводу деплоймента: например, создавать deployment минимум с двумя подами, и тогда появляется проблема для анализа результатов.
Решение: попробовали использовать deployment, но необходимо дополнительно удалять созданные артефакты. Job выполняет задачу один раз и удаляет артефакты сам.
Проблема: как разделить различные окружения — запуск нагрузочного тестирования в dev- и prod-окружениях. Создавать отдельные docker image и манифесты под каждый стенд слишком затратно.
Решение: использовать Kustomize — инструмент для настройки объектов Kubernetes с помощью конфигурационных файлов, разложенных по слоям. Еще используем утилиту SED — редактор для преобразования текстовых данных, чтобы автоматически подставлять нужные нам параметры.
![Структура директорий, которая определяет работу Kustomize. Есть базовый манифест, где описаны общие свойства объектов для всех средств — dev и prod — и overlays, который определяет частные случаи. После запуска базовый манифест патчится с соответствующим образом Структура директорий, которая определяет работу Kustomize. Есть базовый манифест, где описаны общие свойства объектов для всех средств — dev и prod — и overlays, который определяет частные случаи. После запуска базовый манифест патчится с соответствующим образом](https://habrastorage.org/getpro/habr/upload_files/af7/87c/1f3/af787c1f371022deaff7466c53b26377.png)
Проблема: как передавать параметры из Gitlab CI в k8s, потому что иначе эти параметры не знают о существовании друг друга.
Решение: создать скриптом ConfigMap и добавить его в манифест.
![Пример кода для передачи параметров Пример кода для передачи параметров](https://habrastorage.org/getpro/habr/upload_files/9d4/01d/8ea/9d401d8ea1267887ef5c0c108fc529dc.png)
Проблема: логи Gatling. Когда мы запускаем нагрузку, в Gatling пишется очень много логов. Корневой раздел внутри docker-контейнера в нашей инсталляции k8s только read-only, потому что, если записывать в корень данные неконтролируемо, можно получить переполнение дискового пространства на хосте.
Решение: использовать Volume emptyDir. Отличие emptyDir в том, что он живет, пока живет под, который его использует. Еще переопределили параметры запуска sbt: если параметры не определить, то запись будет идти в домашнюю директорию.
![Переопределение параметров запуска sbt Переопределение параметров запуска sbt](https://habrastorage.org/getpro/habr/upload_files/d81/ad4/57a/d81ad457ab66340e8232dab0ea66cdf7.png)
Реализация в Gitlab CI по упрощенной схеме выглядит так:
![Проверяем версии компонентов, версии кода и компиляции в compline и validate, в custom script пользователь может выполнить свои действия, например сгенерировать параметры или данные. В debug test — тест на несколько итераций, чтобы понять, что система работает и корректно отвечает. Далее идет блок с тестами: например, тесты на поиск максимальной производительности или тест-стабильности и тесты, которые работают с Kubernetes. Потом все данные уходят в Cosmos — систему хранения результатов анализов тестов Проверяем версии компонентов, версии кода и компиляции в compline и validate, в custom script пользователь может выполнить свои действия, например сгенерировать параметры или данные. В debug test — тест на несколько итераций, чтобы понять, что система работает и корректно отвечает. Далее идет блок с тестами: например, тесты на поиск максимальной производительности или тест-стабильности и тесты, которые работают с Kubernetes. Потом все данные уходят в Cosmos — систему хранения результатов анализов тестов](https://habrastorage.org/getpro/habr/upload_files/31f/d23/51f/31fd2351f14289fb134456f9a22b86cf.png)
Подробнее про Cosmos от Иоанна Ахальцева:
![](https://habrastorage.org/getpro/habr/upload_files/e41/d3e/219/e41d3e219855cd4c73f932caf55ffefe.png)
В планах — сделать следующие шаги автоматическими:
Запуск тестового стенда для нагрузочного тестирования в k8s.
Проведение нагрузочного тестирования.
Сохранение результатов.
Удаление тестового стенда.
Так экономится значительное количество ресурсов, потому что нам не нужно держать отдельную нагрузочную станцию для Gatling и сам стенд будет запускаться только при необходимости.
Kubernetes оказался не таким сложным, как может показаться на первый взгляд. Все проблемы решаются, если не забывать об ограничениях.
Почитать про Gatling можно в подборке статей на Хабре:
Деструктивное тестирование в рамках тестирования производительности
Руслан Гимазиев, старший инженер по нагрузочному тестированию в Performance Lab, рассказал о деструктивном тестировании, что оно собой представляет, чем отличается от нагрузочного и какие трудности бывают в деструктивном тестировании.
Деструктивный тест — это проверка системы в различных разрушительных условиях. Такие тесты помогают понять поведение системы в разных состояниях инфраструктуры, предоставить дополнительную информацию о проблемах и разработать рекомендации по полученным данным. А еще деструктивные тесты могут уменьшить время простоя системы и сохранить деньги бизнесу.
Главное отличие деструктивного тестирования от нагрузочного — условия, в которых проводится тестирование. Задача деструктивного тестирования — ухудшить условия работы системы так, как это может случиться в реальной жизни, и посмотреть, что произойдет.
![Взаимодействия с инфраструктурой — сетевые взаимодействия или отказ одной из нод. Серверная категория содержит все, что может произойти с сервером. Приложение (система) — поведение самого приложения в тех или иных обстоятельствах. Последняя категория свободная, зависит от особенностей разработки Взаимодействия с инфраструктурой — сетевые взаимодействия или отказ одной из нод. Серверная категория содержит все, что может произойти с сервером. Приложение (система) — поведение самого приложения в тех или иных обстоятельствах. Последняя категория свободная, зависит от особенностей разработки](https://habrastorage.org/getpro/habr/upload_files/76d/0c7/341/76d0c734144e0bfbcc213d3358389430.png)
![](https://habrastorage.org/getpro/habr/upload_files/dfe/d2a/f94/dfed2af946fc2b59adeb0ddbf7ac0857.png)
Пример деструктивного тестирования системы N
Описание: банковский продукт, который принимает финансовые сообщения клиентов и обрабатывает их в определенном формате для передачи в ЦБ и другие организации. Клиент может быть как внутренний, так и внешний.
![Нагрузочный контур сформировали из Perfomance Center и NGINX, приложение развернули на Linux, создали две ноды, написали приложение на Java и завернули в докер-контейнеры Нагрузочный контур сформировали из Perfomance Center и NGINX, приложение развернули на Linux, создали две ноды, написали приложение на Java и завернули в докер-контейнеры](https://habrastorage.org/getpro/habr/upload_files/42d/e3a/607/42de3a607003cfcfe79920b5d4fa34a8.png)
Чтобы провести деструктивное нагрузочное тестирование, мы разработали:
50 скриптов для эмуляции работы сервисов;
2 эмулятора Wiremock — 156 API-эмуляторов и IBM MQ client. Реализовали два разных ответа для разных счетов клиентов и один объемный ответ;
3 развернутые сервисные внешние системы — Kafka, IBM MQ и Logstash;
3 системы мониторинга для двух БД — Telegraf, Oracle Enterprise Manager и Lab128;
5 сценариев для наполнения БД и три сценария для проведения тестов.
Мы разделили все варианты тестов на три группы по сложности, важности и применимости к системе. Выбрали самые важные и получили такой список тестов:
С разными значениями latency от клиента.
![Тестирование показало, что система справляется, только немного выросло время откликов Тестирование показало, что система справляется, только немного выросло время откликов](https://habrastorage.org/getpro/habr/upload_files/53c/7e1/c0e/53c7e1c0e74afb1016a8c19bd828ec43.png)
С медленными ответами внешних систем.
![На графике стабильной подачи нагрузки видно, что когда замедлилось время отклика внешних систем, стали появляться ошибки в бизнес-процессах На графике стабильной подачи нагрузки видно, что когда замедлилось время отклика внешних систем, стали появляться ошибки в бизнес-процессах](https://habrastorage.org/getpro/habr/upload_files/6ae/54b/b94/6ae54bb9453a137825dd20485217b1fb.png)
3. С различной шириной канала передачи входящих и исходящих пакетов от клиента:
![На графиках суммарные интенсивности успешных и неуспешных операций. На графике стабильной подачи теста № 1 видны ошибки, вызванные ограничением канала передачи На графиках суммарные интенсивности успешных и неуспешных операций. На графике стабильной подачи теста № 1 видны ошибки, вызванные ограничением канала передачи](https://habrastorage.org/getpro/habr/upload_files/090/11e/a6f/09011ea6f264f6c892847f1736ad7fb5.png)
Проведенные тесты показали, что скорость для нормальной работы нашего приложения должна быть не менее 512 Кбит/с, задержка latency до 1000 мс и время ожидания клиента не меньше 120 секунд.
Деструктивное тестирование помогает подложить подушку безопасности и понять, в правильном ли месте она установлена.
Вместо заключения
После выступления спикеров провели круглый стол про тренды нагрузочного тестирования в 2023 году. Борис Селезнев, Вячеслав Смирнов и Иоанн Ахальцев обсудили, как выглядят процессы нагрузочного тестирования со стороны бизнеса и команд, которые этим занимаются. Поговорили о том, как бизнес хочет видеть команду тестирования, и ответили на вопросы в чате.
Послушать выступление целиком или скачать презентации спикеров можно на странице мероприятия.
Мы в Тинькофф не только активно применяем, но и много разрабатываем различные инструменты по тестированию производительности. Также мы развиваем наше комьюнити, обмениваемся кейсами и экспертизой, проводим профессиональные встречи и ведем чатик по QA в нашем Телеграме. Чувствуйте себя свободно и не бойтесь задавать вопросы в комментариях.