2009-05-13 6 views
153

Как активировать JMX на JVM для доступа с помощью jconsole?Как активировать JMX на моем JVM для доступа с помощью jconsole?

+30

это разрешено, и на самом деле это только напоминание для меня, потому что я всегда забываю, где скопировать параметры, и теперь я знаю, где я нахожу его :-) – Mauli

+18

Stack Exchange всегда явно призывал пользователей отвечать на свои собственные вопросы, см. здесь: http://stackoverflow.com/help/self-answer –

+10

Не раз я искал SO для чего-то и нашел ответ на вопрос ... сам. И один из них спросил меня. Вот почему хорошо вносить свои собственные ответы. Кроме того, подумайте обо всех других людях, которые, возможно, столкнулись с вашей проблемой, если вы ответите на свой вопрос, вы также будете им помогать. –

ответ

222

Соответствующая документация может быть найдена здесь:

http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html

Запустите программу со следующими параметрами:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9010 
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 

Например, как это:

java -Dcom.sun.management.jmxremote \ 
    -Dcom.sun.management.jmxremote.port=9010 \ 
    -Dcom.sun.management.jmxremote.local.only=false \ 
    -Dcom.sun.management.jmxremote.authenticate=false \ 
    -Dcom.sun.management.jmxremote.ssl=false \ 
    -jar Notepad.jar 

-Dcom.sun.management.jmxremote.local.only=false не обязательно требуется , но без него он не работает на Ubuntu. Ошибка будет что-то вроде этого:

01 Oct 2008 2:16:22 PM sun.rmi.transport. customer .TCPTransport$AcceptLoop executeAcceptLoop 
WARNING: RMI TCP Accept-0: accept loop for ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=37278] throws 
java.io.IOException: The server sockets created using the LocalRMIServerSocketFactory only accept connections from clients running on the host where the RMI remote objects have been exported. 
    at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:89) 
    at sun.rmi.transport. customer .TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387) 
    at sun.rmi.transport. customer .TCPTransport$AcceptLoop.run(TCPTransport.java:359) 
    at java.lang.Thread.run(Thread.java:636) 

см http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6754672

быть также осторожными с -Dcom.sun.management.jmxremote.authenticate=false который делает доступ доступной для любого, но если вы только использовать его для отслеживания JVM на ваш на местном компьютере это не имеет значения.

Update:

В некоторых случаях я был не в состоянии получить доступ к серверу. Это было исправлено, если я также установил этот параметр: -Djava.rmi.server.hostname=127.0.0.1

+8

Теперь на Centos нужен и -Dcom.sun.management.jmxremote.local.only = false – LenW

+0

Nit pick: Мне странно, что 'com.sun.management.jmxremote' имеет значение по умолчанию как' true'. (Спасибо, Солнце!) Чтобы быть предельно ясным, особенно тем, кто менее знаком с JMX nobs, я использую: 'com.sun.management.jmxremote = true' Ref: http://docs.oracle.com/javase/8/ docs/technotes/guides/management/agent.html – kevinarpe

+0

«-Djava.rmi.server.hostname» работал как шарм для меня! –

9

Примечание. Java 6 в последней инкарнации позволяет jconsole присоединяться к запущенному процессу даже после его запуска без заклинаний JMX.

Если это доступно вам, рассмотрите также jvisualvm, так как он предоставляет информацию о запущенных процессах, включая профилировщик.

+3

Это работает, только если вы используете jconsole на том же хосте, что и JVM, который вы пытаетесь контролировать. – Gray

+1

@ Thorbjorn Если я запускаю свою программу java без каких-либо параметров и пытаюсь подключиться к jconsole, я вижу в своей программе список, но когда я пытаюсь подключиться, он терпит неудачу. Я думаю, что это из-за отсутствия сертификатов SSL. Я просто хотел увидеть демо, поэтому мне пришлось использовать параметры, указанные в ответе user3013578, и это сработало для меня (JDK 1.7, Windows 8.1, 64 бит). –

+2

API-интерфейс attach требует, чтобы jconsole имел одну и ту же 32-битную JVM как запущенную программу на некоторых платформах. –

2

Запуск приложения Java со следующими параметрами командной строки:

-Dcom.sun.management.jmxremote.port=8855 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 

Важно использовать -Dcom.sun.management.jmxremote.ssl = ложный параметр, если вы не хотите настройка цифровых сертификатов на хосте jmx.

Если вы запустили приложение на машине, имеющей IP-адрес 192.168.0.1 , открытый JConsole, положить 192.168.0.1:8855 в удаленном поле Process и нажмите Connect.

+0

Каково ожидаемое поведение, если вы забыли '-Dcom.sun.management.jmxremote.ssl = false'? Должна ли 'jconsole' показывать ошибку, или она просто не сможет подключиться? – amacleod

7

Я использую WAS ND 7.0

My JVM нужно все следующие аргументы, которые будут контролироваться в JConsole

-Djavax.management.builder.initial= 
    -Dcom.sun.management.jmxremote 
    -Dcom.sun.management.jmxremote.port=8855 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false 
+0

Да, ваш ответ сработал для меня (JDK 1.7, windows 8.1 64 bit) –

6

В Linux, я использовал следующие Params:

-Djavax.management.builder.initial= 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9010 
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 

, а также я отредактированные /etc/hosts так, что имя хоста решает на адрес хоста (192.168.0.x), а не на адрес обратной связи (127.0.0.1)

19

Запуск в контейнере Docker представил целый набор дополнительных циональные проблемы для подключения, надеюсь, это помогает кому-то. Я в конечном итоге необходимо добавить следующие опции, которые я объясню ниже:

-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=${DOCKER_HOST_IP} -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.rmi.port=9998

DOCKER_HOST_IP

В отличие от использования JConsole локально, вы должны рекламировать другой IP, чем вы, вероятно, см изнутри контейнера. Вам нужно будет заменить ${DOCKER_HOST_IP} на внешний разрешаемый IP (DNS-имя) вашего узла Docker.

JMX Remote & RMI Порты

Похоже JMX также требует доступа к интерфейсу удаленного управления (jstat), что uses a different port передавать данные, когда соединение арбитража. Я не видел, чтобы в jconsole было указано, что это значение. В связанной статье процесс был:

  • Try и соединиться с jconsole с журнализации
  • Сбой
  • Выяснить, какой порт jconsole попытался использовать
  • Использование iptables/firewall правила по мере необходимости, чтобы допустить, что порт для подключения

В то время как это работает, это, безусловно, не автоматизированное решение. Я выбрал обновление с jconsole до VisualVM, так как он позволяет вам явно указать порт, на котором запущен jstatd. В VisualVM добавить новый удаленный хост и обновлять его со значениями, которые коррелируют с теми, указанных выше:

Add Remote Host

Затем щелкните правой кнопкой мыши новое удаленное соединение хоста и Add JMX Connection...

Add JMX Connection

Не забудьте установить флажок для Do not require SSL connection. Надеюсь, это позволит вам подключиться.

+0

Благодарим вас за подробное объяснение, это сэкономило мне время. –