В части 3 этой серии рассматриваются дополнительные инструменты для отладки ваших проектов.

При отслеживании ошибки нам нужно использовать двусторонний подход, аналогичный щипцам, которые оборачивают модуль с ошибкой с обеих сторон и сжимают, чтобы найти проблемную часть. До сих пор мы обсуждали инструменты очень низкого уровня. Некоторые из них можно использовать для отладки служб системного уровня. Сегодня мы обсудим другую сторону стека, но все же очень продвинутый инструмент управления. Чтобы понять это, вам нужно понять, в какой сфере мы находимся.

Как разработчики, мы имеем дело с кодом и приложениями. Развертывание — это для OPS/DevOps, и их инструментарий часто нам чужд. Дело не в том, что у них плохие инструменты. Наоборот, у них есть потрясающие инструменты. Но они обычно предназначены для массового масштаба. Когда вам нужно управлять тысячами серверов, вам нужен способ контролировать все на каждом из них. Для этого нам понадобится другой набор инструментов.

Инструменты управления позволяют нам перемещаться по облакам машин и управлять работающими на них приложениями. Нам не нужен первый, но второй — мощный инструмент, очень полезный для разработчиков. Некоторые стандарты реализуют управление приложениями, а Java представила JMX для инкапсуляции их различий. JMX позволяет приложениям и самому JDK предоставлять информацию и функциональные возможности для обработки внешними инструментами.

Это замечательная функция, которая предоставляет информацию и рычаги настройки для динамического управления в средах выполнения. Активация JMX выходит за рамки этого руководства, поэтому я не буду вдаваться в подробности, но вы можете ознакомиться с некоторыми основами в этой статье Oracle здесь. После запуска мы можем использовать визуальные инструменты для отладки, но я сосредоточусь на инструментах командной строки. Это важно, так как я могу использовать некоторые из этих инструментов непосредственно на рабочих серверах из консоли.

Как работает JMX?

JMX предоставляет «бины» управления (MBeans). Это объекты, представляющие контрольные точки в приложении. Ваше приложение может публиковать свои собственные bean-компоненты, что позволяет вам предоставлять функциональные возможности для мониторинга и настройки во время выполнения. Это очень здорово, так как вы можете экспортировать информацию, которую администратор может напрямую подключить к панели управления (APM, Prometheus, Grafana и т. д.), и использовать ее для принятия решений.

Если к вашему серверу одновременно подключено несколько пользователей, вы можете указать этот номер в JMX, и он может появиться на панели инструментов компании благодаря некоторой связи от DevOps. С вашей стороны, большая часть работы выставит геттер для интересующего значения. Вы также можете предоставить такие операции, как «удалить пользователей» и т. д. Операция — это метод, который вы можете вызывать в JMX-бине.

Spring также поддерживает раскрытие многих сведений о сервере в виде компонентов управления через привод. Это удивительно крутая функция. Вы можете прочитать больше об этом здесь". Он предоставляет очень подробные метрики о приложении и помогает вам сразу перейти к статусу готово к работе!

Основы JMXTerm

Обычно JMX контролируется и читается с помощью инструментов веб-интерфейса или специальных инструментов администрирования. Если у вас есть доступ к любому из них, я предлагаю вам выбрать один из них и использовать его, так как он будет работать очень хорошо. Я использовал некоторые из них в некоторых компаниях, и в некоторых случаях я предпочитаю их. Мне также нравится использовать поддержку IntelliJ/IDEA Ultimates для Actuator, который является довольно мощным инструментом визуализации.

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

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

java -jar ~/Downloads/jmxterm-1.0.2-uber.jar --url localhost:30002

Вы должны обновить имя хоста/порт в зависимости от вашего соединения. После подключения мы можем перечислить домены JMX, используя приглашение:

$>domains
#following domains are available
JMImplementation
com.sun.management
java.lang
java.nio
java.util.logging
javax.cache
jdk.management.jfr

Затем мы можем выбрать конкретный домен для изучения. Именно здесь визуальный инструмент обычно полезен, так как он может обеспечить более быструю навигацию по иерархии и быструю оценку информации. В этом случае я просто хочу установить уровень ведения журнала. Вот как это сделать:

$>domain java.util.logging
#domain is set to java.util.logging

Мы можем проследить это, перечислив bean-компоненты в домене. Затем выберите bean-компонент, который мы хотим использовать, поскольку в этом конкретном домене есть только один bean-компонент. Вот код:

$>beans
#domain = java.util.logging:
java.util.logging:type=Logging
$>bean java.util.logging:type=Logging
#bean is set to java.util.logging:type=Logging

Что я могу сделать с этим бобом? Для этого у нас есть команда info, которая перечисляет операции и атрибуты компонента:

$>info
#mbean = java.util.logging:type=Logging
#class name = sun.management.ManagementFactoryHelper$PlatformLoggingImpl
# attributes
  %0   - LoggerNames ([Ljava.lang.String;, r)
  %1   - ObjectName (javax.management.ObjectName, r)
# operations
  %0   - java.lang.String getLoggerLevel(java.lang.String p0)
  %1   - java.lang.String getParentLoggerName(java.lang.String p0)
  %2   - void setLoggerLevel(java.lang.String p0,java.lang.String p1)
#there's no notifications

Получив их, я могу проверить текущий уровень регистратора. Он не установлен, поскольку мы не установили его явно, и используется глобальное значение по умолчанию. Вот как:

$>run getLoggerLevel "org.apache.tomcat.websocket.WsWebSocketContainer"
#calling operation getLoggerLevel of mbean java.util.logging:type=Logging with params [org.apache.tomcat.websocket.WsWebSocketContainer]
#operation returns:

Я могу явно установить для него значение INFO, а затем снова получить его, чтобы убедиться, что операция работает должным образом, используя этот код:

$>run setLoggerLevel org.apache.tomcat.websocket.WsWebSocketContainer INFO
#calling operation setLoggerLevel of mbean java.util.logging:type=Logging with params [org.apache.tomcat.websocket.WsWebSocketContainer, INFO]
#operation returns: 
null
$>run getLoggerLevel "org.apache.tomcat.websocket.WsWebSocketContainer"
#calling operation getLoggerLevel of mbean java.util.logging:type=Logging with params [org.apache.tomcat.websocket.WsWebSocketContainer]
#operation returns: 
INFO

Это только вершина айсберга. Мы можем получить много вещей, таких как настройки пружины, внутреннюю информацию о виртуальной машине и т. д. В этом примере я могу запросить информацию о виртуальной машине непосредственно из консоли с помощью следующего кода:

$>domain com.sun.management
#domain is set to com.sun.management
$>beans
#domain = com.sun.management:
com.sun.management:type=DiagnosticCommand
com.sun.management:type=HotSpotDiagnostic
$>bean com.sun.management:type=HotSpotDiagnostic
#bean is set to com.sun.management:type=HotSpotDiagnostic
$>info
#mbean = com.sun.management:type=HotSpotDiagnostic
#class name = com.sun.management.internal.HotSpotDiagnostic
# attributes
  %0   - DiagnosticOptions ([Ljavax.management.openmbean.CompositeData;, r)
  %1   - ObjectName (javax.management.ObjectName, r)
# operations
  %0   - void dumpHeap(java.lang.String p0,boolean p1)
  %1   - javax.management.openmbean.CompositeData getVMOption(java.lang.String p0)
  %2   - void setVMOption(java.lang.String p0,java.lang.String p1)
#there's no notifications

Заключение

JMX — замечательный инструмент, который мы в основном используем для подключения консолей управления. Это примечательно тем, что вам очень нужно экспортировать настройки JMX для своих проектов. Сказав это, вы можете перейти на следующий уровень, используя JMX как часть вашего процесса отладки.

Серверные приложения работают без пользовательского интерфейса или с глубоким разделением пользовательского интерфейса. JMX часто может работать как форма пользовательского интерфейса или даже как интерфейс командной строки, как в случае JMXTerm. В этих случаях мы можем инициировать ситуации для отладки или наблюдать за результатами сеанса отладки в пользовательском интерфейсе управления.