qaload | Unsorted

Telegram-канал qaload - 📢 Load & Performance

820

Избранные материалы о тестировании производительности. Чат и источник тем: @qa_load

Subscribe to a channel

📢 Load & Performance

Привет performance lovers!

Это моя мастерская по настройке переключателей скоростей. Состоит из стульев и метелки 🤦‍♂️

Начинал настройку я на балконе, но там холодно 🥶 и света нет. Поэтому постепенно мастерская переехала в комнату

Переключатели настраиваются так, что сначала задний, а потом передний. Но чтобы настроить задний, передний тоже нужен — на среднюю звезду надо как-то поставить все. Разных зависимостей масса

При настройке переднего есть гайды 👨‍💻 с 10-ю шагами, но без описания того а какое состояние вообще исходное — когда все работает, но что-то не так или оно какое-то конкретное — в таких гайдах не хватает еще шагов 0, 1.5, 2.5, ... и их должно быть 21 а не 10

А к чему это я тут ворчу?

В сообществе бывают задают вопросы не про настройку такой "простой" ерунды как переключатель скоростей. А про настройку параметров сложной системы где десятки зависимых элементов, или про инструмент где тоже десятки параметров. В вопросах почти никогда нет всего контекста и текущего состояния. Или исходного состояния. И на такие вопросы как-то отвечают, и ответы даже годные и даже помогают

Я теперь просто не представляю, как людям удается давать годные ответы только по неполному текстовому описанию? И мои ожидания от детальности гайдов по настройке чего-то теперь поднялись на новый уровень. Надо будет сделать что-то по нагрузке

А как я настроил эти перeключатели?

1️⃣ Посмотрел несколько видео, раз 10 посмотрел (часы)
2️⃣ Покрутил, собрал, разобрал, собрал, разобрал (десятки раз)
3️⃣ Снова посмотрел руководства
4️⃣ Вот начало что-то получаться, но все равно не уверен, что правильно
5️⃣ Надо будет поездить и потом перенастроить

Читать полностью…

📢 Load & Performance

Привет performance lovers!

Представьте, что вы применили оптимизацию, но через минуту стало только хуже, и через пять минут — тоже, и через десять...

🫣 Что это, почему так?

🤓 Все хорошо. Это кеши, и первое время они прогреваются и наполняются. Вот видно, что через 17-20 минут они заработали

☺️ Но первые 10 минут я хотел их выключить. Решил, что уже вечер и надо перекусить перед таким откатом, и пошёл за чаем. А когда вернулся — всё уже работало как надо

🤗 Пейте чай!

Читать полностью…

📢 Load & Performance

Привет performance lovers!

Все мы знаем, что профилирование это небесплатная операция, она имеет свою performance цену. Давайте посмотрим, как это может выглядеть на примере профайлера с самыми агрессивными настройками профилирования (включить все)

🔴 Видно что все потоки красные и заблокированы
🟡 Но на Flame Graphs и в стрек-трейсах ничего нет — как будто базовый метод-обертка взял и затормозил

Как такое возможно?

А возможно — профайлер не показывает в данных профилирования сам себя и накладные расходы на профилирование

Я включил все probes и загрузка всех probes замедлила все потоки — без дополнительных инструментов такое не увидеть, но можно было предположить, что так будет

Удачного профилирования!

Читать полностью…

📢 Load & Performance

Привет performance lovers! Я начал забывать

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

Тогда я делал одно упражнение по вечерам — возвращаясь домой вспоминал весь свой день в деталях. Только один день, но очень детально

И это помогало быстро вспоминать что было вчера и неделю назад и месяц

Были и специальные заучивания. В университете у меня была специальная книжка куда я выписывал номера телефонов всех своих знакомых. Я фанат блокнотов и ручек и записей. А выписывание помогало запоминать их

Как-то работая в НПО я заучил и запомнил всех коллег по фото и имени. Не помню сколько человек это было, думаю пару недель учил просматривая карточки в SharePoint снова и снова. Там можно было делать что-то типа SQL запросов к данным и создавать отчёты — только с фото, только с именем, и с фото и с именем

А сегодня мне друг напомнил про поход к водопаду рядом с Иджеваном, а я не помню где это, где Иджеван? Какой из походов это был?

Буду снова ходить домой пешком и по пути вспоминать весь свой день в деталях. И записки надо будет вести активнее, рисунки и схемы рисовать, не полагаться на Google, который найдет.

Надеюсь, когда мы встретимся с вами и возникнет вопрос — а помнишь … — буду помнить

Читать полностью…

📢 Load & Performance

Привет performance lovers! Сегодня снова выходной, снова принес вам водицы. Это уже озеро в горах, холодное, чистое, красивое — чтобы вы отдохнули, подумали свои мысли и были готовы к любым алертам завтра, встречая их с улыбкой 🤗

Из нового — готовили с Мишей Жилиным доклад на Heisenbug и узнал из него как использовать git bisect с тестами производительности. Шел 40-й год жизни, я узнал про эту команду, которая была в git чуть ли не с начала времен 🤦‍♂️

# Вместо good/bad задаём свои слова: fast и slow
# Для поиска регрессий производительности
git bisect start --term-old fast --term-new slow
git bisect fast v5.17 # эта версия быстрая
git bisect slow v5.18 # эта — медленная

git bisect run ./bench.sh # exit 0 = fast, exit 1 = slow

# → 56a4d67c264e — коммит, замедливший систему

В рассказе Миши столько прикольных нагрузочный историй! Если вы будете на конференции завтра, то зайдите к нему, привет передайте

Читать полностью…

📢 Load & Performance

Привет любители производительности!

Собрал промежуточные результаты наших опросов /channel/qa_load/170588. Картина получается интересная: местами предсказуемая, а местами заставляющая задуматься, куда мы идем. 🤩

1️⃣ Кто мы и где находимся
Большая часть нашего сообщества (более 85%) это специалисты из РФ и РБ. Рынок повзрослел: сеньоров и лидов у нас почти столько же, сколько мидлов, а вот джунов совсем мало, меньше 5%. Это подтверждает мысль: простые задачи уходят в AI, и порог входа становится выше

2️⃣ Про деньги и полярность
Медиана нашего рынка — $2 000-$3 500. Но разброс колоссальный:

👑 Верхушка айсберга: Всего 3 человека (около 1.5%) пробили планку в $15 000-$22 000+. Это почти 100% корреляция с рынком США и позициями Staff-уровня.

🦾 Эффект Overemployment: 19 человек работают на 2+ проектах одновременно. Скорее всего, это они сидят в вилке $7 500-$12 000, превращаясь в индивидуальное Performance-агентство за счет AI, экономящего им 40% времени.

📉 Зона турбулентности: 33 человека получают меньше $2 000. При этом работу ищут 27 человек. Рынок насыщен специалистами с опытом 2–3 года, которые конкурируют за все чеки и за низкие чеки тоже

#статистика_нт #карьера_2026

Читать полностью…

📢 Load & Performance

Привет любители производительности!

У меня уходило ~ $10 в день на токены для AI агентов при кодинге. А вчера я запустил тесты агентом, где агент анализировал результаты. Ушло $137, на примерно 11 запусков коротких тестов для разных версий, анализ логов и результатов и сравнительный анализ

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

Сегодня переделал подход, где вместо чтения и анализа логов просто assert
🤩один раз сгенерировал код, который делает тесты на логи и метрики по результатам запуска, это стоило $2-3
🤩теперь JUnit сам дожидается и проверяет все что нужно
🤩запустил все в CI для разных версий, а потом посмотрел на результаты (да вручную, но было недолго)

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

Читать полностью…

📢 Load & Performance

Привет любители производительности!

Согласно аналитике с levels, habr, … в нагрузке в 2026-м платить стали больше, особенно в GPU и AI-проектах

Если есть ускорение за счет AI, использование облаков, k6 и Rust, если уже не просто скрипты, а SRE-путь, …

И всем же интересно что качать, чтобы доходы росли? И здорово понимать, какие вообще сейчас доходы

Вот тут 4 анонимных опроса про локацию, доход, технологии и тренды:

🤩/channel/qa_load/170588/170590

🤩/channel/qa_load/170588/170593

🤩/channel/qa_load/170588/170595

🤩/channel/qa_load/170588/170596

Примите участие в них. Они закроются через месяц автоматически и обсудим результаты. Сравним тенденции и данные аналитиков с тем что видят любители нагрузки своими глазами

Читать полностью…

📢 Load & Performance

Привет любители Linkedin и производительности!

Я слышал про это, но думал, что это шутка. Но в Linkedin встроен детектор расширений браузера Chrome. Написан он коряво и просто перебирает все возможные расширения через HTTP-запросы. И вот сработал для меня сейчас. Проверяется 4278 расширений (на фото 1309 уже проверено) — сайт понятно не грузится и тормозит жестко

Кто-то на...кодил 🤦‍♂️ знатно на главной странице

А расширений у меня в браузере нет. Вот незадача. Лишь тормоза и нагревание воздуха

Из крутого в Sources сейчас по умолчанию показывается сколько раз каждая строка кода выполнилась — профилирование включено по умолчанию

И раз уж этот пост про linkedin — https://www.linkedin.com/in/v8v/ — добавляйтесь в контакты 🤗

Читать полностью…

📢 Load & Performance

Привет performance lovers!

Придумывал как анализировать данные профилирования в pipeline (автоматически)

И придумал схему с InfluxDB

Длительность

🤩1 минута — через такое время после проблемы срабатывает алерт
🤩15 минут — через такое время после запроса данных профилирования, формируется готовый к анализу файл
🤩30 минут — столько времени занимает анализ файла профилирования и формирования отчета
🤩60 минут — в файле профилирования хранятся данные за последние 60 минут с момента сохранения файла

Проблема

В общем, процесс не быстрый
🤩за 1+15 минут успеет случится до 16 алертов

Отработать каждый из них отдельно неэффективно. Ведь у нас есть файл за 60 минут, все 16 алертов туда поместятся

Нужен накопитель

🤩а что если накапливать информацию по необработанным алертам в InfluxDB и отрабатывать их группами

Выбрал тут InfluxDB потому что оказалось просто отправить по HTTP в это хранилище сообщение-метрику

И тот механизм который отправляет алерты через HTTP WebHook в мессенджер, также отправляет теперь и сообщение в базу данных

Нужно теперь обработать алерты

Вот это сложная часть. Пока есть только идеи, как можно это сделать. Дорабатываю инструменты, дроблю и уточняю алерты

Надеюсь, получится через год передать автоматике тот процесс, который сделал уже вручную сотню раз

Читать полностью…

📢 Load & Performance

Привет Performance lovers!

На фото интересный вариант визуализации данных семплирования приложения за 1 час

🤩3600 точек по горизонтали (по количеству секунд и стек-трейсов)
🤩500-800 точек по вертикали (по количеству потоков)

а цветами обозначено состояние потоков:
🤩вот видно, в конце, справа, как произошла недолгая блокировка 🔴
🤩а в середине, были активны Async-потоки, которые ждали ответов от внешних систем 🔵
🤩еще видно как пул потоков jetty постепенно уменьшается, а потом jetty делает всплеск и запускает новую партию активных потоков

Читать полностью…

📢 Load & Performance

Привет performance lovers!

Мы вместе с коллегой занимаемся Observability as code, и обнаружили что для хранения информации по сотне тысяч сервисов InfluxDB (v1) быстро и просто принимает метрики (если вставлять пачками по 10 000), но медленно потом отдает группировки, а вот Postgres позволяет и записать метрики и быстро показать

Думаю надо будет попозже сделать отчёт сравнение. Потому что такие возможности как LIMIT и SLIMIT мы не попробовали даже для InfluxQL:

https://docs.influxdata.com/influxdb/v2/query-data/influxql/explore-data/limit-and-slimit/

И сравнивали на запросе
SELECT * FROM …

Продолжение следует
Подписывайтесь на канал и жмите на 🛎️

Читать полностью…

📢 Load & Performance

Когда и как нагружать MCP?

1️⃣ Почему вопрос возник

Возможно, в вашем продукте появился MCP (Model Context Protocol), и у команды нагрузки появилась задача нагрузить систему по этому протоколу. Так в YouTrack появился MCP сервер, и возникла задача нагрузки

2️⃣ Когда нагружать

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

Да, таким образом нашли несколько неоптимальных методов, которые внутри делали слишком много. Например, при запросе одного поля получали все поля и возвращали одно — а стали и запрашивать и возвращать только одно поле. Небольшие ошибки были

И вот сейчас уже, когда есть статистика использования (спасибо ранним пользователям) и время — стало удобнее сделать тесты производительности

3️⃣ С чего начать

Мне понадобилась хотя бы минимальная статистика о том, что люди (модели) используют. Конечно же, данные, больше данных — больше узких мест. И знание, как пройти аутентификацию.

Тут мне частично повезло
🤩https://www.jetbrains.com/help/youtrack/server/model-context-protocol-server.html
И для моего случая достаточно использовать токен в заголовке, и не пришлось использовать OAuth с редиректами. К 2026-му году версий OAuth уже несколько, в ходу OAuth 2.1. И возможно, ваш новый сервер будет поддерживать именно его. А возможно, у вас пока тоже будет простой вариант аутентификации

Вот несколько полезных ссылок:

🤩https://oauth.net/2.1/
🤩https://stackoverflow.blog/2026/01/21/is-that-allowed-authentication-and-authorization-in-model-context-protocol/

По первой описаны отличия версий 2.1 от 2.0. А по второй есть схема и примеры аутентификации для тестового MCP-сервера. В случае с SSE еще появится шаг с получением SSE-токена

И даже если код писать в паре с агентами, то знать варианты реализации и как поставить задачу нужно человеку

*️⃣ Неочевидные выводы

Хоть MCP на слуху и популярный протокол, большую нагрузку это не создает. Тестирование производительности можно не ставить предусловием к добавлению MCP

Хоть MCP может работать в непростых для тестирования вариантах, как SSE pooling и OAuth 2.1, также есть и более простые для тестирования варианты, как HTTP и аутентификация по токену

Или мне повезло и это эффект выжившего. Пусть и вам повезет!

Читать полностью…

📢 Load & Performance

Hello git lovers!

Неделю выбирал
🤩rebase или
🤩merge

Я работаю в своей ветке, и иногда мне нужно подмержить в свою ветку основной develop, и продолжить работу, подмерживать буду несколько раз. Для такого сценария ничего проще merge не придумали

Но я попробовал делать rebase основной ветки в свою

Один раз можно сделать rebase, а вот если два, то нужно

rebase —-onto …

с указанием базы, тут легко ошибиться. И вот этот второй rebase превращается в сложную задачу. Где ради ровного лога надо сидеть и высчитывать коммиты

merge

экономит время и мыслетопливо — предсказуемый результат, просто указываешь основную ветку и все хорошо, конфликты только там где они были, а не во всех перемещенных коммитах

Читать полностью…

📢 Load & Performance

Сам себя обманул 🤦‍♂️ с профилированием

Настроил на тестовом стенде YourKit profiler с опцией periodic_perf=300 (сохранять снимок на диск раз в 300 секунд). Настроил и забыл

Смотрю на результаты тестов, и раз в 300 секунд скачки на графиках. Мой коллега называет их "вздрыжнями"

🤩Сборка мусора на приложении подумал я, проверил — все хорошо
🤩Сборка мусора на gatling подумал я, проверил — все хорошо
🤩Снизил нагрузку — все равно раз в 300 секунд
🤩И тут я понял, что все дело в профилировании, оно при сохранении блокирует работу потоков ненадолго, на 5-10 секунд, но на графиках это заметно

Отключил periodic_perf=300, убрав этот параметр из строки запуска агента профилирования

https://www.yourkit.com/docs/java-profiler/2025.9/help/agent-startup-options.jsp#trigger

Вот такая получилась строка:
-agentpath:/tools/libyjpagent.so=port=10001,listen=all,probe_table_length_limit=100000,sessionname=youtrack-perf-test,dir=/opt/youtrack/logs,logdir=/opt/youtrack/logs,tmp_dir=/opt/youtrack/temp,triggers_out_dir=/opt/youtrack/logs,cpu=sampling,deadlocks_check_period=10,monitors=on,on_exit=snapshot,snapshot_name_format={app_name}-{datetime},app_name=youtrack_standalone

И стало ровнее

Читать полностью…

📢 Load & Performance

Привет, performance lovers!

Новая загадка с перцентилями

Было применено кеширование, в этом случае кеширование ответов на входящие HTTP запросы, и часть ответов теперь будут кешироваться в браузере, даже не на сервере. И после применения — числа на графиках с перцентилями серверных ответов пошли вверх

Это хорошо. Так и должно быть

Как вы думаете почему это на графике времени отклика есть такой эффект? И какой еще график стоит посмотреть для получения полной картины?

Читать полностью…

📢 Load & Performance

Привет performance lovers!

Снова выходной, снова принёс вам водицы. Это река Изар, слышно как шумят пороги на ней. Неделя была интересной, теперь здорово и отдохнуть

Несколько уроков этой недели

Порядок инструкции в NGinx конфиге важен, каждая следующая дополняет или переопределяет предыдущие. И например нельзя задать размер map-ов уже после определения любой map-ы

Правила NGinx location с регулярными выражениями имеют более высокий приоритет, чем правила location с точным совпадением. Это не было очевидно. В результате, все location правила переписал на регулярки

Если размер JVM MetaSpace недостаточно большой, то при выполнении GC для MetaSpace, эта область памяти очищается, и JVM начинает по новой компилировать код (это пока не 100% истина, но основная рабочая гипотеза отладки одного случая с очень активной компиляцией кода)

Отличных вам выходных! 🤗

Читать полностью…

📢 Load & Performance

Привет любители производительности! Участвую во взаимном продвижении IT-чатов и каналов — "IT в деле" В сборке есть разные тематики

Что внутри:

🧑‍💻 Каналы о программировании и разработке: Python, CSS, HTML, Java и Swift

👨‍💻 GameDev и каналы о QA тестироварии, создание игр и тестирование (мы туть)

🤖 Авторские каналы и вайбкодинг: IT & AI, простые заметки с проектов, работа с нейросетями

🤩 Информационная безопасность: многое узнаете о работе хакеров

Много интересного! Выберите интересные вам каналы или подпишитесь на всю сборку

Читать полностью…

📢 Load & Performance

https://performance.shopify.com/pages/services

Интересная бизнес модель у отличной платформы создания интернет магазинов shopify — можно нанять их команду производительности или команду партнеров 💡

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

Как они добились и как обосновывают?

https://www.shopify.com/enterprise/blog/store-speed-conversion

The trend is clear: for every 100 milliseconds slower a store loads, conversion tends to be about 3.5% lower.


Посчитали, что 100 ms задержки к LCP снижают конверсию (вероятность покупки) на 3.5%

For every 32 milliseconds slower a store responds to interactions, conversion tends to drop by about 1.5%.


А 32 ms к INP также снижают эту вероятность на 1.5%

И чтобы это посчитать они сделали сервис аналитики производительности (встроенный в систему)

https://help.shopify.com/en/manual/online-store/web-performance/web-performance-reports

Отчёт небольшой, использует хранилище Google и просто показывает метрики из него, эти метрики Google и так собирает со всех Google-устройств и Chrome-ов

💰 Их фишка, что они смогли собрать ключевую метрику Conversion rate по сайтам клиентов и соотнести ее с performance метриками

Для этого им скорее всего пришлось постараться и сделать непростой механизм сбора бизнес метрик. Сохранить и обогатить CrUX метрики. Выстроить сеть партнеров с perf-компетенциями. И запустить все

Крутой проект, сколько рабочих мест создано! И как же это красиво подано 🔥

Читать полностью…

📢 Load & Performance

Сегодня хорошая погода. И выходной день. Речка в такой день один из лучших способов отдохнуть, чтобы завтра продолжить тесты писать

Читать полностью…

📢 Load & Performance

Привет любители производительности!

Было ли такое что у вас есть какой-то важный лог в котором явно есть структура и поля в тексте сообщения. Но в Grafana вы можете показать лишь все сообщение целиком

🤩Выделить только часть
🤩Сгруппировать по подстроке
🤩Сделать возможность клика и фильтрации по подстроке
... не получается

В Grafana теперь есть Extract Fields трансформация с поддержкой регулярных выражений
как для однострочных сообщений
/Failed to perform (?<Action>[^ ]+) with unexpected Exception\: Connect timeout has expired \[url=(?<url>[^,]*),/

Так и для многострочных сообщений (заканчивается на /s)
/Failed to perform (?<Action>[^:]+): Status: (?<Status>[0-9]+). Message: Exception during request to (?<url>[^ ]*) with code (?<Code>[0-9]+)\: (?<Message>.*)\nGRAZIE traceID: (?<traceID>[0-9,a-f]+)\n(?<StackTrace>.*)/s

Теперь можно выделять и допаршивать тексты сообщений в браузере и делать невероятно крутые доски по алертам, по специальным классам исключений

Читать полностью…

📢 Load & Performance

Привет любители производительности!

Как подружить Gatling и JUnit 5

Вызов Java-метода
import io.gatling.app.Gatling
Думаю что вы уже знаете, как вызвать Gatling программно

Gatling.main(gatlingArgs);

но вот незадача — там в конце main-вызова есть
.MODULE$.exit(this.fromArgs(args));

и этот код завершит текущий процесс, включая и Junit 5 процесс — все просто схлопнется, но нагрузка выполнится до конца, а вот сделать какой-то assert или обработку в Junit уже не получится

Вызов Scala-метода
import io.gatling.app.`Gatling$`
Можно запустить Scala-класс явно, без Java-обертки которая вызывает exit в конце

`Gatling$`.`MODULE$`.fromArgs(gatlingArgs)


Тут все получится и тест не завершится. Но он не упадет если внутри Gatling сработали ассерты.

Добавить проверку статуса
import io.gatling.app.`Gatling$` + код возврата
Чтобы внутренние ассерты сработали надо еще добавить проверку кода:
  ┌─────────────────────────────┬───────────┬──────────────────────┐
│ Scala case object │ Exit code │ Значение │
├─────────────────────────────┼───────────┼──────────────────────┤
│ StatusCode.Success │ 0 │ Всё ок │
├─────────────────────────────┼───────────┼──────────────────────┤
│ StatusCode.InvalidArguments │ 1 │ Ошибка аргументов │
├─────────────────────────────┼───────────┼──────────────────────┤
│ StatusCode.AssertionsFailed │ 2 │ Assertions провалены │
└─────────────────────────────┴───────────┴──────────────────────┘

Проверка на Kotlin может выглядеть вот так
val exitCode = `Gatling$`.`MODULE$`.fromArgs(gatlingArgs)
if (exitCode != 0) {
throw AssertionError(
"Gatling simulation ${simulationClass.simpleName} failed with exit code $exitCode" +
if (exitCode == 2) " (assertion failures — check Gatling report for details)" else ""
)
}

Читать полностью…

📢 Load & Performance

Привет любители производительности!

Появилась задача тестировать текстовый поиск, текстовый индекс и большие тексты. И подумал — а где мне взять внятный текст большого размера?

Выбор пал на книгу:

🤩https://github.com/dendibakh/perf-book
🤩Denis Bakhvalov - Performance Analysis and Tuning on Modern CPUs

под лицензией "Creative Commons Zero v1.0 Universal"
🤩https://github.com/dendibakh/perf-book/blob/main/LICENSE

В формате MarkDown это 460 КБайт текста. Если сделать статью где будет две таких книги подряд — 920 КБайт, а если три — 1300 КБайт.

Сама книга отличная. И я сразу нашел узкие места, она оказалась еще и очень удачной !!!

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

Читать полностью…

📢 Load & Performance

Привет performance lovers!

Наткнулся на статью
https://jbachorik.github.io/posts/stackprofile-jfr

Где Jaroslav Bachorik (https://www.linkedin.com/in/jbachorik/) рассказывает про jfr-shell и как это можно использовать и как консольную утилиту для работы с профилированием и как MCP-сервер (как основу для скиллов)

И понял что делаю тоже самое. Я тоже работаю над вопросом "When Did That Hotspot Happen?". Мои скрипты генерируют HTML вместо TUI, но идея та же — получение флейм-графа на основе конкретного временного диапазона, группы потоков и паттерна стектрейса:

🤩Выделить блоки из стектрейсов (например, SearchSuggestions.getQueryFeatures)
🤩Подготовить таймлайн с блоками (сверху)
🤩Определить аномалии (outliers) — это необычно долгие блоки среди всех и среди таких же блоков
🤩Выделить временной диапазон с аномалиями и группу потоков (у меня это в 99% случаев потоки qtp)
🤩Агрегация всех блоков с выбранным именем из этого диапазона времени и группы потоков в итоговый флейм-граф

Я сейчас использую YourKit, но думал все что надо перейти на JFR тоже или сделать такой код чтобы и JFR и YourKit поддерживались. А вот получается для JFR уже есть инструменты. И это очень круто!!

Читать полностью…

📢 Load & Performance

Привет Performance lovers!

Оценим отчет по тесту:
🤩Запросы инструментом подаются ровно (верхний график)
🤩А вот ответы в 09:13:10 и дальше нестабильны (нижний график)

Если бы запросы подавались нестабильно, то я бы подумал, что дело в периодической сборке мусора JVM на стороне инструмента нагрузки

Но тут ответы нестабильные, скорее всего дело в периодической сборке мусора JVM на стороне нагружаемого сервера

И действительно — данные телеметрии, которые собираются инструментом профилирования, показывают что это G1 OLD Generation сборка мусора именно в моменты этих всплесков (коллега у меня называет их "вздрыжнями" 😄)

Я пока не настроил полноценное Observability временных тестовых стендов, которые создаются во время работы pipeline. Использую только YourKit snapshot который записывается в каталог логов при остановке процесса и логи приложения. А build-агент потом создает zip-архив с файлами

В дальнейшем сделаю и отправку логов и отправку метрик. Для начала хватает YourKit-а и логов

Возможно, само профилирование потребляет много ресурсов. А может быть нагрузка очень высокая для такого малого тестового стенда. А может стоит добавить некоторые оптимизации

Читать полностью…

📢 Load & Performance

В инструменте FlameGraph Брендена Грегга есть возможность визуально показать на графе новые/другие части другим цветом. Делается за счет того, для каждой строки можно сохранить какой сейчас используется цвет, а потом переиспользовать его при формировании графа для нового профилирования, для которого будет задана другая расцветка

Описано это вот тут — как переиспользовать палитру
https://github.com/brendangregg/FlameGraph?tab=readme-ov-file#consistent-palette
Вот есть два примера
- https://github.com/brendangregg/FlameGraph/blob/master/demos/palette-example-broken.svg
- https://github.com/brendangregg/FlameGraph/blob/master/demos/palette-example-working.svg

А мне захотелось чтобы все вызовы методов работы с БД были одного цвета, все вызовы бизнес-логики другого, ...

Поэтому придумал категории, префиксы категорий и цвета категорий:

# Jetty HTTP server
org.eclipse.jetty.=JETTY_BOILERPLATE

# Jersey JAX-RS (javax.ws.rs. must be before javax. for longest-prefix-wins)
org.glassfish.jersey.=JERSEY_BOILERPLATE
javax.ws.rs.=JERSEY_BOILERPLATE

# Kotlin standard library and coroutines
kotlin.=KOTLIN_STDLIB
kotlinx.coroutines.=KOTLIN_STDLIB

# JVM runtime
java.=JVM_RUNTIME
javax.=JVM_RUNTIME
jdk.=JVM_RUNTIME
sun.=JVM_RUNTIME
com.sun.=JVM_RUNTIME


Вуаля, немного кода, несколько часов отладки, и получаются слои во FlameGraph разных цветов

Читать полностью…

📢 Load & Performance

Привет performance lovers, любители книжек и разработки!

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

А у меня есть AI-агент, который помогает мне код писать. И есть разные подходы, как выполнить сложную задачу и как это описать AI-агенту. Один из способов, может и дорогой, но рабочий такой — дописать в конец непростого задания строку

Запланируй 22 задачи

И если без этого модель пробует в лоб решить задачу, как написание парсера или анализатора или эмулятора. То после такой постановки задачи все начинается не с выполнения, а с планирования десятка шагов (да, получается не всегда 22 задачи, иногда 5, иногда 15). А потом пару раз пройти по списку задач и оценить, где чего не хватает. Так получается тестируемый результат. Небыстро, но мне нравится

Пробую написать скрипты анализа файлов профилирования JVM. Написать к файлам профилирования API, которое решает те задачи, которые решаю смотря на эти данные. Вроде, простая задача. Но ее же не описать одним шагом и запросом. А вот если разбить на десятки, то уже лучше

Читать полностью…

📢 Load & Performance

Hello performance lovers!

Мне понадобилось написать тесты на десятки методов (HTTP API, SSE, WebSocket) и для каждого метода есть еще по несколько вариантов Query String или тел запросов

Также мне хотелось использовать Gatling throttle, для ровной нагрузки по RPS. А для этого надо было сделать сценарии длиной в один запрос — только так работает throttle

Сделал каждый запрос реализацией интерфейса IEndpointChainBuilder
🤩это позволило работать с каждым из них в едином виде
🤩например, добавлять такие методы в Registry методов где будет указан вес метода (влияет на вероятность вызова) и Lambda которая вызывает IEndpointChainBuilder.build()

За основу профиля нагрузки взял randomSwitch().on(...)
🤩это позволяет запускать все методы с весами
🤩подметоды методов можно тоже запускать с весами (randomswitch может быть вложенным)
🤩веса вычисляет класс-утилита Registry, который на вход принимает количества и сам вычисляет проценты в этой группе

Так как часть методов связаны — некоторые ответы являются основной для других запросов, — то добавил механизм Adapter-ов которые добавляют общие классы-хранилища (потокобезопасные Queue или Map) в связанные запросы
🤩атомарные запросы связаны не через Gatling Session, а через общие Queue и Map, заданные через Adapter-ы

Получился расширяемый проект
🤩легко добавить новый метод
🤩легко скорректировать актуальное количество (вес) каждого метода

Чтобы было проще отлаживать добавил к заголовкам каждого запроса X-TEST-NAME, где содержится имя теста:
🤩по заголовкам запроса легко отследить запрос на прокси-сервере как ProxyMan.io

Концепт написал и отладил руками, опираясь на знание Gatling DSL. И когда первые тесты были готовы и отлажены, то за работу по добавлению новых методов и вариаций тел и параметров запросов взялся AI агент Junie, который встроен в 💻 ItelliJ IDEA

Закодировать методы и добавить адаптеры по спецификации агент может с помощью как Gemini так и Opus, выбор модели не так важен

Отладка пока осталась на мне. Но процесс понятный

Читать полностью…

📢 Load & Performance

Hello performance lovers!

Настроил IntelliJ IDEA Plugin — Pretty JSON Log
https://plugins.jetbrains.com/plugin/24693-pretty-json-log
для Gatling

В файле log4j2-test.xml достаточно написать, что будет использоваться JsonTemplateLayout для консоли

    <Appenders>
<Console name="CONSOLE">
<JsonTemplateLayout/>
</Console>
</Appenders>


И добавить зависимости в проект:
    implementation platform('org.apache.logging.log4j:log4j-bom:2.25.3')
runtimeOnly 'org.apache.logging.log4j:log4j-layout-template-json'


И получаются отличные разноцветные логи в консоли. Статистика Gatling отображается просто серым, а сообщения
🟡 INFO
🟠 WARN
🔴 ERROR
отображаются нужными цветами

Началось все с того, что стал настраивать сохранение логов Gatling-теста в ELK, прочитав что Павел Байров подготовил

🖇 https://github.com/Amerousful/gatling-elasticsearch-logs

У нас на проекте используется log4j2, поэтому настройку стал делать под этот формат:
https://logging.apache.org/log4j/2.x/manual/json-template-layout.html

И тут выяснилось, что если JSON логи писать сразу в консоль, то они еще становятся с подсветкой

Читать полностью…

📢 Load & Performance

Hello performance lovers!

Как посчитать минимально необходимое время прогрева перед тестом производительности? На примере Gatling

💡 Самый интересный момент тут в том, что надо сложить и первое время отклика и длительность нестабильности

1️⃣ Была у меня проблема в тесте
В самом начале теста
🤩нагрузка была не самой ровной и
🤩время отклика подскакивало до 10 секунд

2️⃣ Нужен прогрев. Но как долго прогревать?
Можно заметить, что
🤩первые ответы имеют длительность 10 секунд
🤩значит, запросы были отправлены за 10 секунд до отображения этих результатов
🤩и еще 12 секунд после этого время отклика и RPS были нестабильны

Значит прогрев нужен на 22 секунды. А лучше на 30, с небольшим запасом

3️⃣ Для Gatling и Junit (BeforeAll) нужен статический метод запуска
🤩можно передать в параметры запуска
🤩🤩GatlingCliOptions.NoReports
🤩🤩GatlingCliOptions.Simulation
🤩🤩GatlingCliOptions.ResultsFolder
🤩указать что метод запуска static
🤩и запускать его как step_7_warmUp() в @BeforeAll


4️⃣ Прогрев дал результат
🤩Нагрузка стала ровнее

Читать полностью…
Subscribe to a channel