820
Избранные материалы о тестировании производительности. Чат и источник тем: @qa_load
Привет любители производительности!
Как подружить Gatling и JUnit 5
Вызов Java-метода
import io.gatling.app.Gatling
Думаю что вы уже знаете, как вызвать Gatling программно
Gatling.main(gatlingArgs);
.MODULE$.exit(this.fromArgs(args));
`Gatling$`.`MODULE$`.fromArgs(gatlingArgs)
┌─────────────────────────────┬───────────┬──────────────────────┐
│ Scala case object │ Exit code │ Значение │
├─────────────────────────────┼───────────┼──────────────────────┤
│ StatusCode.Success │ 0 │ Всё ок │
├─────────────────────────────┼───────────┼──────────────────────┤
│ StatusCode.InvalidArguments │ 1 │ Ошибка аргументов │
├─────────────────────────────┼───────────┼──────────────────────┤
│ StatusCode.AssertionsFailed │ 2 │ Assertions провалены │
└─────────────────────────────┴───────────┴──────────────────────┘
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 ""
)
}
Привет любители производительности!
Появилась задача тестировать текстовый поиск, текстовый индекс и большие тексты. И подумал — а где мне взять внятный текст большого размера?
Выбор пал на книгу:
🤩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 будет с оптимизациями касательно статей и более быстрой обработки крупных текстов
Привет 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 уже есть инструменты. И это очень круто!!
Привет Performance lovers!
Оценим отчет по тесту:
🤩Запросы инструментом подаются ровно (верхний график)
🤩А вот ответы в 09:13:10 и дальше нестабильны (нижний график)
Если бы запросы подавались нестабильно, то я бы подумал, что дело в периодической сборке мусора JVM на стороне инструмента нагрузки
Но тут ответы нестабильные, скорее всего дело в периодической сборке мусора JVM на стороне нагружаемого сервера
И действительно — данные телеметрии, которые собираются инструментом профилирования, показывают что это G1 OLD Generation сборка мусора именно в моменты этих всплесков (коллега у меня называет их "вздрыжнями" 😄)
Я пока не настроил полноценное Observability временных тестовых стендов, которые создаются во время работы pipeline. Использую только YourKit snapshot который записывается в каталог логов при остановке процесса и логи приложения. А build-агент потом создает zip-архив с файлами
В дальнейшем сделаю и отправку логов и отправку метрик. Для начала хватает YourKit-а и логов
Возможно, само профилирование потребляет много ресурсов. А может быть нагрузка очень высокая для такого малого тестового стенда. А может стоит добавить некоторые оптимизации
В инструменте 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
Привет performance lovers, любители книжек и разработки!
Как выше в блоке про книги писал что мне понравилась книга «Двадцать два несчастья» про доктора Епиходова. В рассказах у него есть виртуальный помощник, который/которая помогает ему людей лечить.
А у меня есть AI-агент, который помогает мне код писать. И есть разные подходы, как выполнить сложную задачу и как это описать AI-агенту. Один из способов, может и дорогой, но рабочий такой — дописать в конец непростого задания строку
Запланируй 22 задачи
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, выбор модели не так важен
Отладка пока осталась на мне. Но процесс понятный
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'
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️⃣ Прогрев дал результат
🤩Нагрузка стала ровнее
Сделал Drill Down по логам сегодня в Grafana. За счет
🤩трёх разных dashboards в которые можно переходить с передачей в них переменных типа Text
🤩Table panel, которая хорошо показывает логи (лучше чем панель Logs), но надо применить трансформацию Extract fields / _source / key+value
🤩И поверх этого Extract Fields с RegExp
Вот представьте что у вас есть в логах строки, которые на поля не парсятся, а там в теле сообщения есть и имя потока и метод и имя сервера. Вот Extract Fields с RegExp может разобрать такие строки на поля уже в браузере
А когда это станет полями, то Table panel активирует Data Links и эти поля становятся кликабельными фильтрами для других досок
Кому это нужно?
Привет performance lovers!
Есть такое состояние мониторинга, когда метрик нет, и это интересная и большая проблема
Некоторые инструменты показывают в это время ровные линии, которые соединяют две точки — эта техника реализована во многих инструментах от Microsoft и например в YourKit Java Profiler
👨⚕️👩⚕️ С такими инструментами чувствуешь себя ❤️ сердечным доктором
Некоторые инструменты не собирают метрик и не показывают их в такие моменты, чем показывают что проблема была и она серьезная
Такие инструменты мне нравятся больше, на них видно, что ничего не видно
Одной из возможных причин такого поведения бывает недостаток памяти по причине ее активной аллокации, и ресурсоемкий процесс освобождения занятой памяти, который вытесняет и ставит на паузу все средства мониторинга
Как найти причину зависания, если метрик нет? Поделюсь мыслями про
🤩логи сервера с исключениями
🤩обрывки профилирования
🤩логи и метрики клиентов
Заходите в комментарии, будем разбираться и лечить
Отлаживал HTTP-тесты, написанные на Gatling, через прокси-сервер. И так как тесты уже разрослись, то в данных прокси-сервера Proxyman все слилось. Понять, какие запросы из какого теста стало сложно
Здорово, что
🤩 можно добавить любые заголовки запроса в Gatling
🤩 получить текущее имя класса в Java
🤩 отобразить заголовки запроса в ProxyMan
static String name=this.getClass().getSimpleName();
...
http("name").get("/")
.header("X-NAME", name)
Интересная новость — Брендан Грегг будет заниматься производительностью ChatGPT в OpenAI
https://www.brendangregg.com/blog/2026-02-07/why-i-joined-openai.html
У него было 26 интервью и встреч, и он делал свой выбор тоже, выбирая по степени полезности проектов для людей вокруг и наличию друзей в компании
Задали мне сегодня вопрос: «А зачем ты это оптимизировал»? Но в вежливой европейской форме: “Какая доля потоков занята этими запросом”?
И в данном случае я и правда оптимизировал то, что было легко сделать, не посчитав предварительно на сколько это критично в числах
🤩 А считать конечно же надо было до, в потом и после, чтобы показать эффект
Как посчитать какая доля потоков на бекенде была занята таким вот запросом?
Есть в nginx такая метрика upstream_response_time, думаю что она поможет мне сделать подсчет по access логам . Напишу потом как получится
Не будьте как я — считаете метрики с важностью оптимизации до оптимизации
Привет любители производительности!
Согласно аналитике с 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
Примите участие в них. Они закроются через месяц автоматически и обсудим результаты. Сравним тенденции и данные аналитиков с тем что видят любители нагрузки своими глазами
Привет любители Linkedin и производительности!
Я слышал про это, но думал, что это шутка. Но в Linkedin встроен детектор расширений браузера Chrome. Написан он коряво и просто перебирает все возможные расширения через HTTP-запросы. И вот сработал для меня сейчас. Проверяется 4278 расширений (на фото 1309 уже проверено) — сайт понятно не грузится и тормозит жестко
Кто-то на...кодил 🤦♂️ знатно на главной странице
А расширений у меня в браузере нет. Вот незадача. Лишь тормоза и нагревание воздуха
Из крутого в Sources сейчас по умолчанию показывается сколько раз каждая строка кода выполнилась — профилирование включено по умолчанию
И раз уж этот пост про linkedin — https://www.linkedin.com/in/v8v/ — добавляйтесь в контакты 🤗
Привет performance lovers!
Придумывал как анализировать данные профилирования в pipeline (автоматически)
И придумал схему с InfluxDB
Длительность
🤩1 минута — через такое время после проблемы срабатывает алерт
🤩15 минут — через такое время после запроса данных профилирования, формируется готовый к анализу файл
🤩30 минут — столько времени занимает анализ файла профилирования и формирования отчета
🤩60 минут — в файле профилирования хранятся данные за последние 60 минут с момента сохранения файла
Проблема
В общем, процесс не быстрый
🤩за 1+15 минут успеет случится до 16 алертов
Отработать каждый из них отдельно неэффективно. Ведь у нас есть файл за 60 минут, все 16 алертов туда поместятся
Нужен накопитель
🤩а что если накапливать информацию по необработанным алертам в InfluxDB и отрабатывать их группами
Выбрал тут InfluxDB потому что оказалось просто отправить по HTTP в это хранилище сообщение-метрику
И тот механизм который отправляет алерты через HTTP WebHook в мессенджер, также отправляет теперь и сообщение в базу данных
Нужно теперь обработать алерты
Вот это сложная часть. Пока есть только идеи, как можно это сделать. Дорабатываю инструменты, дроблю и уточняю алерты
Надеюсь, получится через год передать автоматике тот процесс, который сделал уже вручную сотню раз
Привет Performance lovers!
На фото интересный вариант визуализации данных семплирования приложения за 1 час
🤩3600 точек по горизонтали (по количеству секунд и стек-трейсов)
🤩500-800 точек по вертикали (по количеству потоков)
а цветами обозначено состояние потоков:
🤩вот видно, в конце, справа, как произошла недолгая блокировка 🔴
🤩а в середине, были активны Async-потоки, которые ждали ответов от внешних систем 🔵
🤩еще видно как пул потоков jetty постепенно уменьшается, а потом jetty делает всплеск и запускает новую партию активных потоков
Привет 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 …
Продолжение следует
Подписывайтесь на канал и жмите на 🛎️
Когда и как нагружать 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 и аутентификация по токену
Или мне повезло и это эффект выжившего. Пусть и вам повезет!
Hello git lovers!
Неделю выбирал
🤩rebase или
🤩merge
Я работаю в своей ветке, и иногда мне нужно подмержить в свою ветку основной develop, и продолжить работу, подмерживать буду несколько раз. Для такого сценария ничего проще merge не придумали
Но я попробовал делать rebase основной ветки в свою
Один раз можно сделать rebase, а вот если два, то нужно
rebase —-onto …
rebase превращается в сложную задачу. Где ради ровного лога надо сидеть и высчитывать коммиты merge
Сам себя обманул 🤦♂️ с профилированием
Настроил на тестовом стенде 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
И стало ровнее
Hello performance lovers!
Я большой любитель тетрадей и блокнотов. В Ижевске в шкафу лежит сумка с записями. В Москве еще одна. В Мюнхене стопка. А в рюкзаке всегда со мной пара блокнотов
Некоторые тетради и блокноты очень старые. Больше всего мне пригодились блокноты с контактами и паролями, начал вести их осознанно и регулярно, где-то в 2007-м
🤩записи с контактами были очень актуальны, когда на SIM-карту помещалось несколько десятков контактов, а телефоны менялись/ломались раз в год без возможности переноса контактов между устройствами
🤩записи с паролями стали актуальны, когда погрузился в безопасность и стал делать сложные уникальные пароли на каждый случай, а случаев было много, сотни
Блокноты переживают переезды, повреждения жестких дисков, смену сервисов — бумага очень надежный носитель информации, который устойчив к нагрузкам
Тут стоит сказать и что можно записать, и куда, и чем. И поделиться хочу находками:
🤩Ручки Pilot, конкретно FriXion, 0.5 — шариковые роллеры с тонкой и легкой линией, и со стирающимися быстросохнущими чернилами. Писать ими легко, чернила негустые
🤩Еще не видел плохих ручек с шариком 0.5 и не видел плохих ручек от Pilot
🤩Часто можно найти в магазинах ручки 0.7 — больший шарик, чуть больший расход чернил, и они более густые, поэтому нужно больше сил прилагать. Но тоже хорошо
🤩Гелевые пишут легко, но расход большой и они сохнут дольше или даже мажут — нужна плотная бумага (90 g/m2) и нужно ждать пока все высохнет перед закрытием
🤩А в школе у меня, думаю, были ручки 1.0, с большим шариком, и там усилий надо было много — часто их расписывал, ведь большой шарик засыхал, а то что колпачок надо закрывать я не думал
Хорошую бумагу я открыл для себя в 2018-м. Это был блокнот 📓 70 g/m2, который я забыл где-то в переговорке Райффайзен банка и так и не нашел. И бумага такой плотности была просто шелковой по сравнению с тетрадками, которые использовал ранее
Да есть у блокнотов минус — их можно забыть. Поэтому удобно хранить важную бумагу в рюкзаках, а не в руках
Большая удача найти тетрадь на спирали с плотностью 90. Почему удача — с такой плотностью часто продают более дорогие красивые блокноты в толстой обложке, обложка изумительная, бумага тоже, но часто они сделаны как книга, и их сложно разложить на столе не помяв. А вот спиральки раскладываются без помятия. Слышал и про японские блокноты, которые раскладываются без помятия, хоть и не используют спирали, но не пока не было опыта, не видел их
Сегодня интерны вышли на работу, ко мне тоже
Будем вместе делать мониторинг для YouTrack. Продукт сразу будет идти с мониторингом и алертами
Пусть получится и коллегу себе подготовить и продукт
А через два дня открывается подача заявок на новый набор интернов в JetBrains. Там есть проект по предсказанию метрик в облаке. Менторы будут в Амстердаме
☕️ Есть такая JVM библиотека Caffeine, отличная. Можно строить с ней кеши где у ключей есть срок годности
И вот я писал тесты с OAuth токенами. И подумал — вот возьму библиотеку готовую для токенов, не буду делать на ConcurrentHashMap-е
Взял. Сделал тест с Gatling. Уперся в ❎ DeadLock, когда одновременно ключи добавлялись, читались, и выполнялся внутренний CleanUp для Caffeine
Починил пока написав обертку над Caffeine-вой Map-ой, которая ставит 🔒 RetainLoc, что на чтение, что на запись. Сделал однопоточный кеш. Вроде все хорошо теперь. Может немного потерял в скорости, но отказываться от удобной таблицы уже не хотелось
Отлаживал аутентификацию OAuth. Кто знает про передачу JWT-токенов в относительных ссылках для GET-запросов, те знают, что относительные ссылки (которые #token={JWT|base64}) не всегда отображаются в прокси-серверах или даже на вкладке Network.
И я не сразу вспомнил про это и немного плутал. Чтобы лучше запомнить, да и вам напомнить, поделюсь картинками:
🤩В Network в секции Response Headers в заголовке Location для первого-второго запроса будет JWT-токен
🤩В Console если включить логирование запросов тоже будет виден JWT-токен, уже просто в Requests URL
🤩Но вот в Network в Request URL относительных ссылок не будет видно в браузерах
🤩И в прокси-серверах тоже относительные ссылки не показываются, например в ProxyMan, в URL
Это тот тонкий момент, когда параметры запроса есть только в предыдущем ответе и они скрываются при отображении этого запроса, почти везде
Представьте, что вы отвечаете за доступность и корректность работы большой системы, и у вас может быть есть явная роль SRE. Но вы так хорошо работали, что нет ни алертов ни проблем
Или вы запустили тест производительности, а он прошел хорошо, также как обычно, и даже никаких дефектов не завести ...
... кажется, что не завести никаких дефектов
На этот случай рекомендую открыть логи и посмотреть на их количество. Моя любимая фича в хранилище логов OpenSearch это Top 5 values по ключевым полям логов. А любимые поля это
🤩service, чтобы отфильтровать по сервису
🤩source или file, чтобы выбрать конкретный лог, если сервис пишет несколько логов
🤩level, чтобы оставить ERROR или WARN
🤩class (иногда это называется logger)
🤩message с текстом сообщения
Обычно достаточно сделать фильтры по
🤩service = главный сервис
🤩source = основной лог
🤩level = ERROR
и посмотреть на TOP-5 по полю
🤩class
Потом можно сделать фильтрацию только по TOP-1 значению, получить messages от этого класса, часто они будут очень похожи друг на друга. И тут вы сможете понять, что вот она ошибка, скрывалась, но нашлась
Такие удобные фильтры как TOP 5 values есть и OpenSearch Dashboard и в Kibana и в Grafana
Ни теста без дефекта!!
Задали мне сегодня вопрос «Есть ли у меня план-бекап?» И вопрос был задан в контексте того, а вот отключится все электричество года так на два — двадцать два — что будешь делать?
И тут я подумал, что нагрузкой больше заниматься не буду.
Надо бы научится чему-то полезному, людей лечить, например, или зверей хотя бы. Существо я социальное, хоть и проводил в лесах и горах много времени, но жить там полностью автономно не смогу. А по-хорошему мне в такой ситуации хотелось бы проделать путь длиной примерно в 3-4 месяца пути (пешком или на транспорте, как велосипед), родных проведать. На таком пути будет здорово знать языки и уметь людям помогать как-то
Год назад начал разбирать Memory Leak при просмотре результатов теста во View Result Tree, для случая больших файлов в запросах или ответах
Это задача 6336, разобрал тогда в какие моменты выделяется память и что она не очищается даже после Clear All.
Автор дефекта получил проблему на больших запросах (Request), а я проверял на ответах (Response)
Некоторые наблюдения из этого разбора
🤩тема System работает на 2 минуты быстрее темы Darklaf - Dracula (detault) при открытии результатов теста с большими файлами
🤩настройки на лимиты размеров текста при отображении, не делают объем хранимиго в памяти текста меньше — думаю что можно оставлять только начало ответа еще при загрузке результатов
🤩дедупликация строк не используется, если открыть два одинаковых ответа или запроса, то память выделится тоже дважы
Тут я говорю про настройки JMeter
## MAX_DISPLAY_SIZE
view.results.tree.max_size=10485760
## MAX_LINE_SIZE
view.results.tree.max_line_size=110000
## SOFT_WRAP_LINE_SIZE
view.results.tree.soft_wrap_line_size=100000
## Дудупликация строк
-XX:+UseStringDeduplication
## Работает с G1GC:
-XX:+UseG1GC
## Сколько поколений сборки мусора надо пережить (3 по умолчанию)
-XX:StringDeduplicationAgeThreshold=1
## Надо будет добавить 100ms к длительности пауз (по умолчанию в JMeter 100)
-XX:MaxGCPauseMillis=200
view.results.tree.max_size=10485760 байт, если результат загружается из файла (при просмотре результатов в live-режиме обрезать результат нельзя)String.intern() для некоторых больших строк (думаю это точно нужно только для JMX-файлов и для тел запроса в режиме чтения тела запроса из файла