Что нового в нагрузке

для меня в 2022 году?

Смирнов Вячеслав, Miro

Image by Vlad Gerasimov on https://vlad.studio/

Ускоряю Miro

Развиваю @qa_load

Изучаю языки и технологии

2007, 2018, 2022 : хакер,тимлид,инженер

https://dvdbash.com/2013/01/20/the-x-files-gallery-season-1/

1️⃣ Что нового в нагрузке сделал я?

2️⃣ Что нового в нагрузке сделали другие?

Image by Vlad Gerasimov on https://vlad.studio/

1️⃣ Что нового в нагрузке сделал я?

Image by Vlad Gerasimov on https://vlad.studio/

📝 Цель — создать сообщество performance-инженеров в компании

Собираем вещи, есть работа

https://dvdbash.com/2013/01/20/the-x-files-movie-i-want-to-believe-2008/

Другой язык, AWS и облака, тестирование в облаках

🆕 Развитие коммуникативных навыков, английский язык и тесты в облаках важны

📝 Тестирование обновления и масштабирования кластера

⚙️ Hazelcast, JUnit, Jenkins, Prometheus, Grafana

Старая версия системы работает, пусть 100 узлов

Новая версия запускается (с запасом), пусть + 120 узлов

Старая версия системы останавливается, в итоге 120 узлов

Быстрый рост на 120-150% и быстрый спад

Что нужно протестировать?

Быстрый рост кластера распределенных кешей

Быстрый спад кластера распределенных кешей

Быстрый рост пула подключений к базе данных

...

Как быстро можно запускать и останавливать?

На каком размере кластера можно обновляться?

Малый кластер успевает синхронизироваться

Большой кластер не успевает синхронизироваться

Большой кластер не успевает синхронизироваться

  • Размер пакета с состоянием кластера растет x 2.2-2.5

  • Количество обновлений состояний кластера растет x 2.2-2.5

  • Если 1 запрос работает 1 мсек, то 1000 узлов — предел для кластера

  • И значит на кластере в 400 узлов обновляться еще можно

  • А на кластере в 500 узлов обновляться уже нельзя

  • Был выбран размер в 200 узлов

🆕 Делать сложную задачу на стыке Test и Ops можно простыми инструментами

📝 Выявление медленных и частых SQL-запросов

⚙️ Grafana, ElasticSearch, OpenSearch

Пример структурированного лога

_index: elk-logs-20220607
date: 2022-06-07 15:15:15
level: WARN
server: app-api-000123
function: app-api
thread: http-thread-001234
logger: com.miro.SlowQueryExceptionWrapper
accountid: 0987654321
exceptionLine1: com.miro.ComponentName.ClassName:987
exceptionMessage: SlowQueryException 
with time 10123 ms limit 1000 ms 
with query /*traceId:09876543210987654321*/ 
SELECT id, name, date FROM tableName WHERE date < now()

По части полей точно можно фильтровать и группировать

_index: elk-logs-20220607
date: 2022-06-07 15:15:15
level: WARN
server: app-000123
function: app-api
thread: http-thread-001234
logger: com.miro.SlowQueryExceptionWrapper
accountid: 0987654321
exceptionLine1: com.miro.ComponentName.ClassName:987
exceptionMessage: SlowQueryException 
with time 10123 ms limit 1000 ms 
with query /*traceId:09876543210987654321*/ 
SELECT id, name, date FROM tableName WHERE date < now()

А часть полей слишком уникальные

_index: elk-logs-20220607
date: 2022-06-07 15:15:15
level: WARN
server: app-000123
function: app-api
thread: http-thread-001234
logger: com.miro.SlowQueryExceptionWrapper
accountid: 0987654321
exceptionLine1: com.miro.ComponentName.ClassName:987
exceptionMessage: SlowQueryException 
with time 10123 ms limit 1000 ms 
with query /*traceId:09876543210987654321*/ 
SELECT id, name, date FROM tableName WHERE date < now()

Добавим в Grafana названия полей как переменную-список

Сделаем Repeat-панели с таблицей и графиком по списку

_index,
date,
level,
server,
function,
thread,
logger,
accountid,
exceptionLine1,
exceptionMessage,
...

По каждому значению можно отфильтровать в один клик

🆕 Grafana и repeat-панели позволяют быстро находить узкие места по логам

📝 Составить профиль нагрузки

⚙️ Jaeger, Kibana, ElasticSearch, OpenSearch

🆕 Применение Jaeger и OpenTracing для анализа профиля нагрузки в Kibana

📝 Растиражировать тесты по командам и увеличить покрытие профиля нагрузки

⚙️ k6

Переход к простым тестам, вместо сложных на 100 ручек

export function setup() {
    return do_auth(CONF.url, CONF.login, CONF.token);
}
export default function (auth) {
    if (__ITER == 0) do_apply_cookie(auth, CONF.url);
    http.get(`${CONF.url}/api/v1/accounts/${CONF.accountId}`,{
        tags: { name: '(GET) /api/v1/accounts/ID' }});
}
export function teardown(auth) {
    do_apply_cookie(auth, CONF.url); do_logout(CONF.url);
}
export function handleSummary(data) {
    return do_handleSummary(data);
}

auth — результат аутентификации, data — статистика

export function setup() {
    return do_auth(CONF.url, CONF.login, CONF.token);
}
export default function (auth) {
    if (__ITER == 0) do_apply_cookie(auth, CONF.url);
    http.get(`${CONF.url}/api/v1/accounts/${CONF.accountId}`,{
        tags: { name: '(GET) /api/v1/accounts/ID' }});
}
export function teardown(auth) {
    do_apply_cookie(auth, CONF.url); do_logout(CONF.url);
}
export function handleSummary(data) {
    return do_handleSummary(data);
}

Меняется одна функция и конфиг при тиражировании

export function setup() {
    return do_auth(CONF.url, CONF.login, CONF.token);
}
export default function (auth) {
    if (__ITER == 0) do_apply_cookie(auth, CONF.url);
    http.get(`${CONF.url}/api/v1/accounts/${CONF.accountId}`,{
        tags: { name: '(GET) /api/v1/accounts/ID' }});
}
export function teardown(auth) {
    do_apply_cookie(auth, CONF.url); do_logout(CONF.url);
}
export function handleSummary(data) {
    return do_handleSummary(data);
}

🆕 Переход к простым тестам на узкое место, на проблему

📝 Написать регрессионные нагрузочные тесты-метрики backend'а, как замена Jaeger

⚙️ k6, VictoriaMetrics, Prometheus, InfluxDB, Grafana

Slides https://polarnik.github.io/grafana-comparator/

🆕 Давать метрики командам, важнее, чем отчет и баги по производительности

📝 Запускать тесты с разными профилями на разных стендах, с разных агентов и локально

⚙️ docker, docker-compose

Параметризация тестовых данных, стенда и профиля

  k6_test_accounts:
    image: grafana/k6:0.40.0
    restart: "no"
    volumes:
      - "./src/test/config/:/tmp/src/test/config/:ro"
      - "./src/test/k6/:/tmp/src/test/k6/:ro"
      - "./results/k6_test_account:/tmp/results/:rw"
    environment:
      - TEST_CONFIG=perf-environment-1.big-workload.json  # Стенд и тестовые данные   
      - K6_RPS=20                                         # Интенсивность (профиль)
      - K6_VUS=20                                         # Время отклика (SLA)
      - K6_ITERATIONS=10000                               # Длительность теста
    working_dir: "/tmp/results/"
    command: "run --insecure-skip-tls-verify
    --out influxdb=http://influxdb:8086/k6 
    /tmp/src/test/k6/test_accounts.js
    "

Для Taurus надо будет получить ENV с профилем скриптом

  k6_test_accounts_taurus:
    image: blazemeter/taurus:1.16.17
    restart: "no"
    volumes:
      - "./src/test/config/:/tmp/src/test/config/:ro"
      - "./src/test/k6/:/tmp/src/test/k6/:ro"
      - "./results/k6_test_accounts:/tmp/results/:rw"
      - "./src/test/bzt-configs/:/bzt-configs"
      - "./results/k6_test_accounts_taurus:/tmp/artifacts:rw"
      - "./src/test/k6/lib/taurusOpts.js:/tmp/src/test/k6/lib/commonOptions.js:ro"    
    environment:
      - TEST_CONFIG=perf-environment-1.big-workload.json  # Стенд и тестовые данные   
      - K6_RPS=20                                         # Интенсивность (профиль)
      - K6_VUS=20                                         # Время отклика (SLA)
      - K6_ITERATIONS=10000                               # Длительность теста
    working_dir: "/tmp/results/"
    command: "/bzt-configs/test_accounts.yaml"

В Docker можно монтировать и каталог и файл в каталоге

  k6_test_accounts_taurus:
    image: blazemeter/taurus:1.16.17
    restart: "no"
    volumes:
      - "./src/test/config/:/tmp/src/test/config/:ro"                                 
      - "./src/test/k6/:/tmp/src/test/k6/:ro"                                         
      - "./results/k6_test_accounts:/tmp/results/:rw"
      - "./src/test/bzt-configs/:/bzt-configs"
      - "./results/k6_test_accounts_taurus:/tmp/artifacts:rw"                         
      - "./src/test/k6/lib/taurusOpts.js:/tmp/src/test/k6/lib/commonOptions.js:ro"    
    environment:
      - TEST_CONFIG=perf-environment-1.big-workload.json  # Стенд и тестовые данные   
      - K6_RPS=20                                         # Интенсивность (профиль)
      - K6_VUS=20                                         # Время отклика (SLA)
      - K6_ITERATIONS=10000                               # Длительность теста
    working_dir: "/tmp/results/"
    command: "/bzt-configs/test_accounts.yaml"

🆕 Запуск тестов из Docker удобен и перспективен

📝 Автоматизация нагрузки по расписанию или кнопке

⚙️ Jenkins, Pipeline, Python, Ansible, Terraform

Работа со стендом и метриками наиболее сложны

  • Восстановление системы из снимка
  • Обновление версии системы
  • Запуск и подготовка системы к тестированию
  • Запуск тестов производительности
    • Запомнить время старта
    • Запустить профилирование до старта
    • Тест, скрипт подачи нагрузки
    • Сохранить результаты теста
    • Сохранить системные метрики за тест
    • Сохранить логи, результаты профилирования и ссылки
    • Сравнить метрики и отправить нотификации о деградации
  • Остановка системы
  • Остановка окружения

🆕 Облачный тестовый стенд автоматически создается для тестирования

📝 Написать регрессионные нагрузочные тесты-метрики frontend'а, как замена Jaeger

⚙️ sitespeed.io

Потрясающие отчеты

Просто потрясающие отчеты

А если нужна аутентификация?

В конфиге теста настроим использование user-data-dir

    "chrome": {
      "enableTraceScreenshots": false,
      "includeResponseBodies": false,
      "ignoreCertificateErrors": true,
      "collectConsoleLog": true,
      "collectLongTasks": true,
      "collectNetLog": true,
      "args": [
        "user-data-dir=/tmp/user-data-dir/",
        "no-pings",
        "no-report-upload",
        "no-first-run",
        "no-default-browser-check"
      ]
    }

Сначала сделаем аутентификацию в папку user-data-dir

  sitespeed_login:
    image: sitespeedio/sitespeed.io:25.11.0-plus1
    volumes:
      - "./src/test/config/:/sitespeed.io/test/config/:ro"
      - "./src/test/javascript/:/tmp/src/test/javascript/:ro"
      - "./report:/sitespeed.io/sitespeed-result/:rw"
      - "./user-data-dir:/tmp/user-data-dir/:rw"
    restart: "no"
    command: "--config /sitespeed.io/test/config/login.json 
    /tmp/src/test/javascript/app-auth-login-basic.js
    -n 1"

А потом тесты с той же папкой user-data-dir

  sitespeed_test_miro_wo_cache:
    image: sitespeedio/sitespeed.io:25.11.0-plus1
    volumes:
      - "./src/test/config/:/sitespeed.io/test/config/:ro"
      - "./src/test/javascript/:/tmp/src/test/javascript/:ro"
      - "./report:/sitespeed.io/sitespeed-result/:rw"
      - "./user-data-dir:/tmp/user-data-dir/:rw"
    restart: "no"
    command: "--config /sitespeed.io/test/config/test.json 
    /tmp/src/test/javascript/clear.js
    https://domain.com/someUrl-for-testing
    -n 3"

🆕 Тесты фронта с sitespeed.io делаются просто, приносят массу пользы

2️⃣ Что нового в нагрузке сделали другие?

Image by Vlad Gerasimov on https://vlad.studio/

Андрей Похилько, UP9, быстрый mock server, Mockintosh

UP9, сетевой отладчик k8s, Mizu

Андрей Сатарин, исследование сбоев при обновлениях

Mark Tomlinson, Performance Exploration For Testers

Андрей Акиньшин, Профессиональный бенчмарк


Generated by https://huggingface.co/spaces/PaddlePaddle/ERNIE-ViLG
Generated by https://huggingface.co/spaces/PaddlePaddle/ERNIE-ViLG
Generated by https://huggingface.co/spaces/PaddlePaddle/ERNIE-ViLG

Будущее будет быстрым

AWS, своих датацентров никто не строит, специфика Украины - все хостится в облаках, в России - все хостятся у себя. Облачные реалии наступают. В связи с переездом многие вещи. Изменились. Вот я никогда не работает с AWS и тестирование нагрузки в облаках это другое. Вы не понимаете - это другое.

Иллюстрация Тестирование обновления кластера. 1000 - 2000 нод. Squisse, тестирование одной ноды на проде до ее пределов. Потом две ноды. Проверка линейности масшабирования системы.

Берем простые вещи и тестируем сложную систему. Берем ото всех по чуть-чуть и получаем исследование, которое находится на стыке Test и Ops.

Написание тестов на узкое место. Написание маленького теста на проблему.

Команды пугают другие вещи - мы делали-делали, подали нагрузку, а тут вот ... медленно стало. Команды хотят Feature toggle. Тестированеи производительности 1) Проверка по факту 2) Метрики на проде, трейсинг, который покажет, в чем узкое место Arrange, Act, (Assert) !!!!! Сделать более яркий переход между слайдами голосом. Интонацией.

Почему раньше не запускали тесты из Docker? Были проблемы производительности самого Docker. Сейчас он позволяет. Istio, Envoy, balancer, ... Особенно, когда тестируются сервисы развернутые в k8s Разработчик может запустить нагрузку локального с локальной машины разработчика

Много денег надо будет за облако. И для нагрузки становится важно развертывать и свертывать конрут нагрузки.

lithhouse -- для ручной проверки. А тут как LH с мониторингом

- Андрей Похилько - новый инструмент для нагрузки и Mizu.io - отличная утилита для разбора проблем в Kubernetes - Илья Бровкин - новая платформа для Web3 https://www.linkedin.com/in/iliyabrovkin/ - Олесь Писаренко - новый инструмент для нагрузки на GoLang https://www.linkedin.com/in/doctornkz/ - Андрей Сатарин - https://www.linkedin.com/in/asatarin/ тестирование корректности распределенных систем во время обновления и отката версиий в дополнение к стресс-тестированию в помощью unit-тестов, выполняемых во время обновления или масштабирования системы https://asatarin.github.io/talks/2022-09-upgrade-failures-in-distributed-systems/ - Андрей Акиньшин - новая книга Профессиональный бенчмаркинг - Антон Серпутько - работает в США, участвовал в подкасте по производительности https://t.me/dou_qa/484 - Mark Tomlinson - сделал курс по эксплуатационному тестированию производительности, тестирование цель которого в поиске узких мест и записал много новых выпусков подкаста PerfBytes https://www.linkedin.com/in/mtomlins/ - Paul McLean - предоставляет API для тестовых данных, https://www.youtube.com/watch?v=bFAICy5j35M https://www.linkedin.com/in/paulmclean2/ интересные материалы, тестирование производительности Starlink и геораспределенное тестирование с помощью Gatling, тренды тестирования приоизводительности в 2021 году https://www.youtube.com/watch?v=z3yvh4syuqw и https://www.mammoth-ai.com/top-performance-engineering-trends-5-things-your-team-needs-to-know/ - Joe Calantonio, Performance & SRE Podcast https://testguild.com/podcasts/performance/ и https://www.linkedin.com/in/joecolantonio/ - Andreas Grabner https://www.linkedin.com/in/grabnerandi/ OpenTelemetry, Keptn - Federico Toledo, jmeter-java-dsl https://www.linkedin.com/in/federicotoledo/ - Vitaly Friedman, https://www.linkedin.com/in/vitalyfriedman/, - Alex Xu, https://www.linkedin.com/in/alexxubyte/ System Design - 🤠Leandro Melendez (Señor Performo) https://www.linkedin.com/in/leandromelendez/ интервью с разными инженерами - Henrik Rexed https://www.linkedin.com/in/hrexed/ Observability, Dynatrace, OpenTelemetry, eBPF - Jason Arbon, test.ai, https://www.linkedin.com/in/jasonarbon/ Batch вставка результатов тестов, после выполнения всех тестов это быстрее, чем вставка результатов тестов после каждого теста - Mehdi Daoudi, Cachpoint https://www.linkedin.com/in/mdaoudi/ - Kent Beck, - Stephen Townshend, https://www.linkedin.com/in/stephentownshend/ - Jeff Barr, - Delvis Echeverria, https://www.linkedin.com/in/delvisecheverria/recent-activity/ - Denis Bakhvalov, https://www.linkedin.com/in/dendibakh/ -