Введение
Жил был (и живёт дальше) один проект на Alfresco, можно сказать высоко нагруженный, его разработка началась много лет назад и текущая команда уже далеко не первая и даже не вторая. Начиналось всё, как обычно, клиент хотел чуток «кастомизировать» стандартный функционал, а в итоге переписано и переопределено почти всё.
И так система работала не сказать, что быстро, но после очередных обновлений стало ей совсем грустно, пошли жалобы от пользователей. 🙁 В общем надо было, что-то с этим делать.
Трудность заключалось в том, что проблема была видна только на продуктивных серверах, там где одновременно работало много тысяч пользователей, воспроизвести замедление не удавалась полноценно на тестовых стендах при нагрузочном тестировании.
Была попытка профилировать продуктовые сервера с помощью JProfiler-а, который в любом режиме профилирования приводил к почти полной неработоспособности сервера, так пользовательская нагрузка + профилирование приводили к тому, что приложение вообще переставало отвечать или отвечало с такими задержками, что смазывало всю картину в статистике профилирования, да и хотелось иметь возможность, посмотреть как чувствовало себя приложение в какой-то конкретный момент времени, например когда поступали жалобы в тех.поддержку.
Таки образом нам нужен был инструмент, который может профилировать, семплировать, собирать и хранить статистику.
Glowroot — собственной персоной
Для решения вышеуказанных проблем был выбран Glowroot как инструмент внутрисерверного профилирования. Glowroot представляет собой приложение состоящие из двух основных компонентов:
— серверная часть (glowroot-central)
— агенты (glowroot agent), которых может быть несколько на один glowroot-central
Принцип их работы следующей, есть запущенное приложение glowroot-central, оно на отдельном порту ожидает входящие подключения агентов glowroot и затем принимает от них входящие данных (телеметрию), которые сохраняются и могут быть позже использованы для анализа.
Агенты в свою очередь работают на стороне профилируемого приложения и собирают данные с него, а затем передают в glowroot-central. Ниже приведена примерная схема Glowroot (рис.1)
Glowroot-Central
Это Java приложение поставляемое в виде jar-файла, которое можно оформить в виде serivice-а или просто запустить «java -jar glowroot-central.jar…», также рядом лежат конфигурационные файлы для переопределения настроек по умолчанию.
После запуска, если ничего в настройках не меняли, то на порту :4000 появляется web-интерфейс (рис.2)
Само приложение Glowroot-central можно разделить на две логические части.
- Сборщик — эта часть отвечает за поддержания связи с агентами, принятие входящих данных и их сохранение в СУБД Cassandra DB. Тут не случайно выбрана данная СУБД т.к. она разрабатывалась специально для работы с большими данными в аналитических системах т.е. то, что нам нужно.
- Web-интерфейс (UI) — сюда можно включить HTTP сервер, систему выбора данных их БД, их трансформацию и агрегацию, а затем вывод в интерфейс в виде графиков, списком удобных для анализа.
Также можно задавать свои параметры\правила для профилирования и сбора данных, это касается раздела Конфигурации и Инструментирования, т.е. после создания своего правила, оно передаётся в агенты, которые его применяют и что самое приятное, без перезапуска профилируемого приложения. Детальнее об это будет описано ниже.
Здесь же просто хотелось обратить внимание, что glowroot-central и glowroot-агенты имеют двухстороннюю связь, а не только поток данных идущий из агентов в glowroot-central.
Glowroot-агенты
Это тоже java-приложение, которое запускается вместе с исследуемым приложением, чтобы иметь возможность его инструментировать и профилировать.
Пример запуска приложения benchmarks c агентом:
java -jar benchmarks.jar -jvmArgs -javaagent:path/to/glowroot.jar
Также для агента задаются параметры с указанием расположения glowroot-central, хост и порт если он расположен удалённо.
На этом наверное закончим описание основных блоков приложения Glowroot и пройдём по более прикладным вопросам.
Интерфейс и инструменты
Панель выбора: Список агентов
В этом выпадающем списке отображаются агенты по которым есть данные за выбранный период. Здесь выбираете интересующие вас приложение и далее только по нему будут выводиться данные для анализа.
Панель выбора: Тип транзакций
Этот выпадающий список обычно содержащий три пункта:
- Startup — вывод данных которые были собраны на этапе запуска профилируемого приложения. Тут может быть полезная информация для поиска проблем запуска приложения или для ускорения процесса запуска приложения.
- Background — это данные собранные по потокам, которые не были порождены входящими http-запросами. Это различные scheduler-ы и job-ы, запускаем по расписанию или по триггеру от каких либо событий не связанных с http-запросами.
- Web — это как раз противоположность Background, здесь будет выводиться информация по потокам, которые были порождены http-запросами, сюда же попадают потоки, которые были запущены основным http-потоком.
Также тут могут появиться другие типы, которые можете сами создавать при создании своих правил инструментирования в соответствующем разделе.
Разделы: Transactions
В данном разделе мы можем просмотреть трассировку от входящего http-запрос до того момента, как поражённые им потоки будут делать запросы в БД или другие источники данных. С уверенностью можно сказать, что это главный функционал Glowroot.
B так в левой панели мы видим список запросов, которые glowroot трассировал и сохранил для нас за выбранный интервал времени, на скриншоте этот интервал Last 2 day (Последние 2 дня). Они расположены по убыванию сверху вниз в зависимости их кол-ва за период, т.е. наиболее «горячие» сверху.
В основной панели на вкладке Response time отображается график в миллисекундах по выбранной транзакции или по всем, если выбран самый верхний пункт «All Web Transaction 100%». В этом графике отображены разными цветами, разделения по типам транзакций, т.е. можно анализировать на, что больше всего приходит нагрузка и как она коррелируется другими типами.
Далее перейдём на вкладку Slow Traces этой же панели
Здесь на графике маркерами отображаются запросы (транзакции), которые исполнялись долже заданного параметра, который определён в настройках glowroot. Этот параметр можно задать в разделе Configuration->Transactions->Slow threshold. По умолчанию 2сек.
Раздел Slow Traces (рис.6) полезен тем, что мы можем отслеживать запросы которые выполнялись не нормально долго для нас. И потом нажав на маркер на графике рассмотреть его детально.
По клику на марке открывается модальное окно (рис.8)
Вверху указал URL по которому был сделан запрос для Web или наименование объекта если это Background. Справа от запроса есть иконка в виде облачка со стрелка, по клику на неё происходит выгрузка этого окна со всеми подразделами, это может быть полезно, если разработчики не имею доступа к glowroot, который работает в продуктивной среде и им надо передать данные для анализа.
Далее детально не будут расписывать каждый пункт в этом окне, там в принципе всё очевидно из названий. Но отдельно пройдёмся по внутренним разделам этого окна.
Первый раздел с рисунка 9 — это Trace entries, в нём можно посмотреть последовательность запросов к БД или иному источнику данных (solr, elastic… если это настроили), в виде последовательности с таймлайноми рис. 10
Чем большее заполнение тайлайна приходится на запрос тем больше времени он исполнялся относительно остальных. Эта информация очень полезна для поиска не особо оптимальных запросов к БД.
Далее следует раздел Query Stats (рис.11)
Здесь собирается сгруппированная статистика по запросам, т.е. можем увидеть какой запрос сколько раз вызывался в рамках одного обращения по исследуемому http-запросу. Так же видно сколько времени в средним выполняется этого типа запрос и сколько строк возвращает.
Если видим, что как-то запрос выполняется чрезмерно много раз и при этом возвращает одно и тоже, то возможно стоит подумать, а том, чтоб прикрутить кеш или просто хранить значение в переменной пока оно может быть нужно в рамках транзакции. Тут вообще можно много, что полезного узнать, для оптимизации кода.
Следующий раздел — Profile (рис.12)
В этом разделе отображаются stacktrace-ы с процентами, эти проценты указывают как долго каждый узел выполнялся относительно общего времени. По каждой строке можно кликнуть и будет развёрнут внутренний трэйс. У этого раздела есть представление в виде Flame Graph.
Это были наиболее важные инструменты Glowroot. Далее более бегло рассмотрим все остальные.
Раздел Errors
В этот раздел попадают транзакции, которые завершились исключением(ошибкой). Они также были видны и в разделе Transactions на рис.6 в виде красных маркеров на графике, но они там были вперемешку с тему, которые успешно завершились. В общем можно сказать, что здесь отображает то же самое, но с фильтром по ошибкам. Также нажимаете на маркер на графике и смотрите детальную информацию по транзакции.
Раздел JVM
Тут можно сделать выгрузку Thread dump-а, посмотреть работу GC и настройки\параметры профилируемого приложения, MBean (JMX) и другое.
Остальные разделы, являются специфическими и малоиспользуемые, потому в рамках статьи их не буду затрагивать.
Настройки Instrumentation
Ещё кратко хотел бы рассказать про инструментированния классов и методов, для сбора более детальной информации с их вызовов, а также когда они долго работаю и выходят за рамки транзакции.
Рис.15 — Раздел Instrumentation
Здесь можно создать новое правило инструментирования, которое будет применено на агентах, без всяких перезагрузок.
Для этого нажимаем Add new
В Class name начинаем вводить полное имя класса с пакетом и glowroot нам подскажет если найдёт его у агентов, затем также вводим метод этого класс в Method name, всё по тому же принципу с подсказками если найден.
Также есть галочка any signature — это значит, что будут инструментированы все методы с таким именем без учёта их сигнатуры по аргументам иначе выбрать конкретный метод.
Далее What is capture тут выбрать, как и что будет захватываться:
1.Transacton
2.Trace entry
3.Timer
Transaction type — это как раз те разделы Web, Startup, Background в выпадающем списке, тут можно указать один из них, либо вписать своё значение и оно будет добавлено в список.
Transaction name — наименование транзакции, это как она будет отображаться в списка, обычно указывается имя метода
Остальные параметры думаю понятны из их названия и не нуждаются в описании.
Также добавлю, что Правила инструментирования можно экспортировать и импортировать в виде json. И не забывайте после создания нового правила или редактирования имеющегося нажимать кнопку Apply под списком правил инструментирования иначе обновления не будут отправлены агентам и, следовательно, не будут работать.
Всем удачных оптимизаций кода!