Повышаю качество более десяти лет. Занимаюсь системой дистанционного банковского обслуживания юридических лиц. Основной профиль моей работы — тестирование производительности. Развиваю сообщество инженеров по тестированию производительности, помогая коллегам в telegram чате «QA — Load & Performance». Занимаюсь оформлением дефектов и предварительными действиями для этого: профилированием JVM, оптимизаций SQL-запросов, разработкой досок в Grafana, группировкой логов в Kibana. Автоматизирую все, что сделал несколько раз. Давно не писал скрипты, но поддерживаю навык за счет ответов на вопросы коллег. Работаю в продуктовой команде. Но у нас в системе более 400-т сервисов. Из-за большого количества сервисов на поддержке наша продуктовая команда - сервисная, с большим беклогом, когда все надо сделать вчера
Я к сожалению или к счастью не занимаюсь заведением дефектов. Да, раньше я это тоже делал, но сейчас у нас чуть другой подход к НТ, я говорю у нас т.к. сложно делать НТ для ГК Тинькофф в одного, когда у тебя каждый день 100 релизов разных приложений как монолитных так и микросервисных. Поэтому мой подход заключается в том, чтобы дать инструменты командам, которые сами все сделают. Про это я и поведаю вам далее.
# В чем отличия Максим: Кто отвечает за НТ в принципе и какая у нас роль. Мы не всегда делаем НТ всего. Часто НТ делает команда сама, а мы лишь делаем ревью скриптов и их результаты. Да, у нас есть бизнес-линии как мы это называем или продукты например инвестиции, финансовые системы и т.д. на бизнес-критичных системах мы безусловно обращаем большее вниманием и помогаем им в приоритетном порядке. Слава: У нас есть разделение на сервисы платформы и прикладные сервисы. Сервисы платформы наиболее нагруженные, делаем НТ сами. И помогаем командам с профилированием, пишем для команд дефекты, в которых указано в какой строке кода сервис тормозит. # Что общего Работаем IT-компаниях, предоставляющие банковские услуги. Где пишут и оптимизируют свой же код. Работаем в командах нагрузки, в которых сосредоточена экспертиза по тестированию производительности. В сравнимых условиях и сравнимых командах, но очень разных.
Максим: у нас канбан. Мы работаем как сервисная команда и как я говорил ранее кроме проектов НТ у нас есть свои проекты по разработке инструментов НТ и поддержки инфраструктуры вокруг них. По этому наши задачи разделены на 3 больших блока: стандартные проекты НТ, поддержка и развитие инфраструктуры и собственно разработка инструментов НТ. Приоритет у нас больше смещен в пользу последнего.
Слава: у нас тоже был канбан, вытягивали. Теперь скрам - планируем. Но планируем с фактором неопределенности. Заводим много дефектов и задач в беклоги других команд, и они возвращаются на нас с некотроллируемой скоростью, как срочные задачи, которые надо проверить в ближайшее время. Стенда три, а инженеров больше 6-ти, и мы часто работаем по двое. Это увеличивает оценку задач. Поэтому используем контейнеры на задачи, чтобы погасить фактор неопределенности. Например, 3 дня мы будем оптимизировать SQL-запросы. А какие именно, кто именно, пока не знаем.
Слава: Пропорции продуктива с более высокой интенсивностью На продуктиве есть механизм КПЭ (контрольных показателей эффективности), внутренняя аналитика. На ее основе строится соотношения в профиле нагрузки. Если известно, что карточка документа открывалась за неделю 10 000 раз, а сохранялась 9 000 раз, то мы знаем, что только 90% открытий приводит к сохранениям и учитываем пропорцию в профиле. А интенсивность увеличиваем до отказа, зная, что прошли 1 продуктив, 2 продуктива, ... 20 продуктивов. Профиль получить и реализовать в скриптах несложно. Сложно получить и согласовать SLA. В качестве SLA используются продуктивные метрики КПЭ.
Слава: Фиксированные стенды, одно плечо продуктива На стенды нагрузки выделено ресурсов столько же, сколько на продуктив. Но на продуктиве распределенный кластер на два плеча. А для нагрузки два отдельных стенда. Это позволяет проводить тестирование параллельно и на нагрузке выше продуктива. Для локализации дефектов и проверки исправлений по ним используются третий небольшой стенды.
Максим: чаще используем отдельные NS в кубе или же контур в облаке openstack. Либо 1 стенд на несколько систем т.е. в 1 момент времени там залита лишь 1 система, а в другой другая. Системы объединены по направлению какому-то и у них должны быть одинаковые потребности по ресурсам. Стараемся делать 1 плечо прода - 1 датацентр либо 1 плечо нагрузки если есть балансер до. Почему так, у нас очень много систем и мы быстро растем и держать контур лайк-прод нам не очень удобно.
Что общего Тестовые стенды у нас хорошие. В банках редко бывают плохие тестовые стенды. В чем отличия Слава: Почему стенды фиксированные - тестовые данные очень сложно сохранить и восстановить, их слишком много. Даже если восстановить все БД полугодовой давности, то накат миграций на террабайтные базы данных будет длиться вечно. Поэтому миграции на базы данных накатываются регулярно и не откатываются, и стенды привязаны к базам данных. Максим: Ansible, Terraform, Packer, Gitlab-CI и helm или kustomize чарты позволяют создать кластер на лету. Также у нас автоматизирован сбор снимков с продуктива и их обезличивание. Получается: фиксированные БД == фиксированные стенды создаваемые по запросу БД == создаваемые по запросу стенды И тестовые данные играют ключевую роль
Слава: Сгенерированные во время тестирования Хорошо бы тестировать на реальных данных, но это невозможно. Доступа до них просто нет. И чтобы знать производительность завтрашнего дня, надо иметь больше данных, чем на проде. За счёт регулярных запусков тестов на стенде НТ много данных. И дисковое пространство наш самый критичный ресурс. Плюсы - есть возможность находить узкие места, раньше, чем на продуктиве. Минусы - можно услышать в ответ на дефект, что на продуктиве все быстро, хотя версия та же. Фишка - данные не такие как на продуктиве. Их больше. И они не сентетические, они как настоящие.
Максим: Клон БД с прода с обфусцированные данными. Либо генерируем данные в пустой БД или в БД с уже существующими данными. У нас много генераторов данных для ФТ и АТ, мы можем использовать их. Фишка - данные, такие как на продуктиве (по количеству и распределению).
Что общего Алгоритмы + структуры данных = программа Никлаус Вирт Стенд с сервисами + тестовые данные = нагрузочный стенд Инженер НТ Для тестов НТ данные необходимы. Так или иначе их надо иметь. Обфусцированные, генерирование, любые - они нужны. Да побольше, да побольше В чем отличия Максим: Так ведь если данные не такие как на продуктиве, то тест не настоящий!!!! Надо делать как на продуктиве Слава: Да, но если не делать данных больше, чем на продуктиве, то как же спрогнозировать нагрузку завтрашнего дня? И вообще, если обезличить данные, то ФИО из Смирнов Вячеслав и Семенов Степан превращается в Иван1 Иванов и Иван2 Иванов, статистика едет, связки ломаются, запросы становятся другими или вообще перестают работать: в одной таблице номер один, а в другой таблице номер другой и ничего не работает. Если надо тестировать на продуктивных данных, то это без деперсонализации и сразу на продуктиве. Но мы так не делаем
Максим: А мы так делаем. Ха, ха!!! Не тестируется то, что списывает деньги, вроде.... Но сервисы, не списывающие деньги, можно нагрузить. Тестирование проводится вместе с командами, вместе с SRE в моменте. Подается нагрузка и оценивается, как система себя ведет. И нагрузка отключается, если что-то идет не так Фишка в том, что можно проверить всю цепочку интеграций. Мы также можем перенаправлять трафик. За счет балансировки нагрузки. Нагрузить одну станцию из 4-х не на 25% нагрузки, а на 60% или 100%, посмотреть, как она себя поведет под большей нагрузкой. Эта нагрузка, которая создается реальными клиентами, не нагрузочными тестами. Также можно вывести ноду из ротации и нагрузить ее синтетической нагрузкой. Максим: А почемы вы так не делаете?! Слава: Так это же рискованно. Разве у вас ничего не ломалось при этом и все шло как надо?
Максим: Нет, не ломалось. Мы не доводим нагрузку до 100%. 100% меряется по SLA: утилизация, время отклика и APDEX. Если так не делать, не тестировать на проде. То сложно получить реальную нагрузку. И не получится протестировать всю систему.
Мы на продуктиве не тестируем. Регулярно запрашиваем и анализируем статистику с прода. По SQL-запросам в частности. Иногда профилируем проблемные сервисы под живой нагрузкой.
Слава: Все протестировать нельзя. За всеми графиками не уследить, получим просто Alert Storm. Можно протестировать все в рамках одного вида теста, контролируемого, более узкого Максим: Да, но это зависит от вида теста
Слава: Интеграционные тесты на поиск максимума и подтверждение Основные тесты - регрессионные. Дополнительные тесты - просто сделать замеры в браузере. Спрофилировать и найти узкие места. А также такие же тесты но на больших объемах данных. Тоже просто в браузере. Эмуляция работы крупных клиентов. По вкладку в количество и качество дефектов, они такие же как регрессионные. Третья группа тестов - уменьшенный регрессионный. На подтверждение исправления дефектов. Делается на небольшом стенде в четыре шага: Эталонный тест Установка обновления Контрольный тест Сравнение
Максим: Тесты распределены по уровням зрелости процесса НТ в команде. Начало это макс.перфы, подтверждение и надежности - в виде бенчмарков. Затем уже интеграция, хаузтестинг и т.д. У нас все эти же тесты есть. Но если мы пишем тесты сами, то делаем команде лишь Debug (Smoke) и MaxPerf с подтверждением. Это минимальный набор тестов. А все остальное команды делают сами по крайней мере мы к этому идем. Вот список остальных тестов: интеграция, между другими компонентами Chaos Testing объёмное повторение проблем прода стресс тестирование Squeeze тестирование
Слава: Сквиз тестинг, это что такое? Максим: Это бред из нетфликса. Ты выводишь одну ноду из ротации. И грузишь ее до упора. Получаешь значение в RPS. Скейлишь и нагружаешь ее снова. Слава: У нас это делается так. Убраны лимиты подам. И выставлены их скейлинги. 1. Перезапустить сервисы и нагрузить тестом MaxPerf 2. Получить kubectl top (CPU Time поды / длительность жизни поды) и сгруппировать результаты по сервисам 3. Профилировать то, что потребило больше всех CPU и память 4. Скейлить, как запасной вариант Максим: Вы делаете лишь стандартные тесты. И не раскрываете все ситуации. А мне кажется, что надо делать так, чтобы разработчики запускали быстрые бенчмарки у себя. И не ждали нагрузочного контура. Разработчики запускают тесты на своих машинах. Слава: А как же автоматизация? Максим: Да, мы идем к тому, чтобы бенчмаки запускались тоже в CI/CD, поднималась пода с сервисом, обстреливалась тестом и получался результат.
Максим:
Максим: в основе у нас Gitlab CI, Nexus, Docker. А мы YAML-Developer-ы, pipeline в Gitlab-CI похож на Docker-Compose + Jenkins. Плюс: все в одном месте, все стандартизируется и переиспользуется. За счет Gitlib-CI и Docker. Запуски выполняются на любом генераторе нагрузки. У нас несколько видов под разные типы тестов.
Максим: А почему вы не делаете также? Слава: Мы, возможно, придем к такому. Сейчас у нас свой Jenkins и свои агенты, чтобы не замедлять другие команды. Чтобы тесты производительности, которые выполняются долго и требуют много ресурсов, никак не замедляли процессы сборок команд разработки. Но мы планируем в этом году перейти в общебанковскую инфраструктуру. А вот про запуск тестов из Docker пока не думал, это интересно
Слава: Настроенные правила парсинга логов на поля в logstash, работа на основе ELK Мы настроили всем сервисам единый формат логирования. Передав свои logback-конфиги в каждый. А для единого формата логирования уже настроен парсер лога на поля: время, уровень, сервис, поток, класс, сообщение, исключение. Также logtash позволяет создавать поля на основе полей, кодом на JRuby, поэтому сообщения маскируются, чтобы по ним можно было делать группировку. Такие структурированные логи позволяют быстро выявлять проблемы. Ранее, когда не был настроен единый формат логов и парсинг, использовались скрипты на python, которые выгружали логи сервиса из ELK в формате CSV и парсили его, а результат парсинга сохранялся в InfluxDB в виде статистики. Теперь исходные данные и поля для группировки в ELK.
Максим: у нас внутренняя разработка как средство мониторинга логов на основе ELK. В нее выгружаются логи всех приложений и мы осуществляем поиск проблем и алертинг на их основе. Команда разрабатывающая продукт сама заводит логи в данную систему и заинтересована в их поддержании и настройки алертов в актуальном состоянии.
Максим: мы не пишем отчеты вообще. Да, это так. Сейчас расскажу как мы к этому пришли. У нас все логи собираются в 1 месте, все графики мониторингов тоже в 1 месте и данные с генераторов нагрузки у нас тоже в 1 месте, а ещё у нас же есть требования SLA и NFR, без которых мы не запускаем НТ. А значит у нас есть все, чтобы сделать отчёт мечты - автоматически. Да, хочется сразу оговориться, что мы ещё не научились определять уровни макс.перфа и т.п. но вот сравнивать тесты регресса можем, а также подгружать все графики в 1 место. Все графики и анализ привязываются к запускам теста из gitlab-ci и можно провалиться в каждый отчет и посмотреть как и что шло.
Кто делает запуски тестов Максим: Мы запускаем лишь базовые тесты, когда сами пишем скрипты как я говорил ранее, дальше команда сама. Если команда писала сама скрипты, то она сама и всё запускает. Да, мы можем проконсультировать в любой момент команду по любому вопросу связанному с порядком запуска или анализом проблем. Кто поддерживает тесты? Максим: у нас это на команде разрабатывающей проект т.к. ещё раз повторюсь она отвечает за его качество и команде НТ физически не может уследить за всеми изменениями во всех системах ГК Тинькофф какого бы размера она не была, мы это приняли как факт. Да, мы конечно помогаем в сложных ситуациях или когда команда не знает как и что поменять в скрипте. Также мы можем расширить функционал тестов по запросу команды например добавить новый протокол или сделать сложный сценарий, но чаще мы лишь делаем пример на скажем 1 запрос, а команда дальше сама дорабатывает свой скрипт с нашими консультациями. Почему так? Возможно это выглядит жестоко, но только так можно научить людей, что-то делать самих т.к. сделав все за них они при новой любой проблеме снова придут к вам, а это уже контрпродуктивно.