JConsole — хороший инструмент для мониторинга работающего Java-приложения. Но когда невозможно подключиться к JVM напрямую с помощью JConsole (например, из-за сетевых ограничений) и туннелирование SSH невозможно, было бы здорово иметь версию JConsole для командной строки.
jcmx — это такая версия командной строки JConsole. После загрузки одного jar-файла cjmx_2.10-2.1.0-app.jar
вы можете запустить его, включив tools.jar в classpath:
1
|
java -cp $JAVA_HOME/lib/tools.jar:cjmx_2. 10 - 2.1 . 0 -app.jar cjmx.Main |
Откроется «оболочка JMX» со следующими основными командами:
- help : показывает основной экран справки, который объясняет доступные команды.
- jps / list : Как и инструмент jps из JDK, эта команда печатает все процессы Java с их идентификатором процесса.
- connect : вы можете использовать эту команду для подключения к работающему процессу JVM.
- формат : давайте вам укажем, хотите ли вы вывод в простом текстовом формате или в виде строки JSON.
- выход : выход из приложения.
Чтобы узнать больше о cjmx, давайте запустим сеанс и подключимся к JVM, на которой запущен сам cjmx:
1
2
3
4
5
6
7
8
9
|
> jps 13198 cjmx.Main > connect 13198 Connected to local virtual machine 13198 Connection id: rmi: //0:0:0:0:0:0:0:1 2 Default domain: DefaultDomain 5 domains registered consisting of 19 total MBeans > describe disconnect exit format help invoke mbeans names names sample select status |
После последнего появления> вы видите замечательную особенность cjmx: автозаполнение. Каждый раз, когда вы не знаете, какие команды доступны, вы можете просто ввести [TAB]
и cjmx выведет их список. Это даже работает для имен MBean, как мы увидим.
Теперь, когда мы подключены к нашей JVM, мы можем позволить cjmx описать доступный MBean. С помощью автозаполнения мы можем просто начать вводить describe '[TAB]
чтобы получить список всех доступных пакетов:
1
2
|
> describe ' : JMImplementation: com.sun.management: java.lang: java.nio: java.util.logging: |
Таким образом, мы можем копаться в именах MBean, пока не найдем то, что ищем. В этом примере нас интересует MBean ‘java.lang: type = OperatingSystem’:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
> describe 'java.lang:type=OperatingSystem' Object name: java.lang:type=OperatingSystem ------------------------------------------- Description: Information on the management interface of the MBean Attributes: MaxFileDescriptorCount: long OpenFileDescriptorCount: long FreePhysicalMemorySize: long CommittedVirtualMemorySize: long FreeSwapSpaceSize: long ProcessCpuLoad: double ProcessCpuTime: long SystemCpuLoad: double TotalPhysicalMemorySize: long TotalSwapSpaceSize: long AvailableProcessors: int Arch: String SystemLoadAverage: double Name: String Version: String ObjectName: ObjectName |
Как мы видим, MBean ‘java.lang: type = OperatingSystem’ предоставляет информацию о количестве открытых файлов и текущей загрузке процессора и т. Д. Итак, давайте mbeans
количество открытых файлов, вызвав команду mbeans
с именем MBean, а также подкоманда select
и атрибут MBean:
1
2
3
4
|
> mbeans 'java.lang:type=OperatingSystem' select OpenFileDescriptorCount java.lang:type=OperatingSystem ------------------------------ OpenFileDescriptorCount: 35 |
Мы можем даже запросить все доступные атрибуты, используя звездочку вместо конкретного имени атрибута. Обратите внимание, что использование клавиши курсора вверх вызывает последнюю введенную команду, поэтому нам не нужно вводить ее снова. Вместо этого мы просто заменим имя атрибута звездочкой:
1
2
3
4
5
6
|
> mbeans 'java.lang:type=OperatingSystem' select * java.lang:type=OperatingSystem ------------------------------ MaxFileDescriptorCount: 10240 OpenFileDescriptorCount: 36 ... |
С помощью invoke
мы можем даже вызвать методы MBean, как в следующем примере:
1
2
|
> mbeans 'java.lang:type=Memory' invoke gc() java.lang:type=Memory: null |
Теперь, когда мы знаем, как запрашивать атрибуты и вызывать методы, мы можем приступить к созданию сценариев этой функции для мониторинга приложения. Для поддержки этого вида сценариев cjmx предоставляет возможность передавать все «команды» также в качестве аргумента самого приложения, поэтому вы можете вызывать cjmx следующим образом (где <PID> должен быть заменен конкретным процессом). идентификатор работающей JVM):
1
2
3
4
|
java -cp $JAVA_HOME/lib/tools.jar:cjmx_2. 10 - 2.1 . 0 -app.jar cjmx.Main &lt;PID&gt; &quot;mbeans 'java.lang:type=OperatingSystem' select OpenFileDescriptorCount&quot; java.lang:type=OperatingSystem ------------------------------ OpenFileDescriptorCount: 630 |
Обладая этими знаниями, мы можем написать простой скрипт bash, который каждую секунду запрашивает у JVM количество открытых файлов:
1
2
3
4
5
6
|
#!/bin/bash while [ true ] ; do echo ` date ` | tr -d '\n' java - cp /usr/java/default/lib/tools .jar:cjmx_2.10-2.1.0-app.jar cjmx.Main $1 &quot;mbeans 'java.lang:type=OperatingSystem' select OpenFileDescriptorCount&quot;| grep OpenFileDescriptorCount| cut -f 2 -d : sleep 1 done |
Это создает каждую секунду новую строку с отметкой времени и текущим количеством открытых файлов. Когда мы перенаправлены в файл, у нас есть простой файл журнала и мы можем оценить его позже.
Вывод : cjmx является отличной альтернативой JConsole, когда последний не может быть использован из-за сетевых ограничений на сервере. Возможность даже выдавать команды, передавая их в командной строке, делает его подходящим для небольших сценариев мониторинга.
Ссылка: | cjmx: версия JConsole для командной строки от нашего партнера по JCG Мартина Мойса из блога Martin’s Developer World . |