Як активувати JMX на моєму JVM для доступу до jconsole?


223

Як активувати JMX на JVM для доступу з jconsole?


32
це дозволено, і насправді це лише нагадування для мене, тому що я завжди забуваю, звідки скопіювати параметри, і тепер я знаю, куди його знаходжу :-)
Mauli

20
Стек Обмін завжди явно закликав користувачів відповісти на свої запитання, дивіться тут: stackoverflow.com/help/self-answer
Tim Buthe

11
Не раз я щось шукав ТАК і знаходив питання, на яке відповів ... сам. І один із них мене теж запитав. Ось чому добре скласти власні відповіді. Також подумайте про всіх інших людей, які, можливо, зіткнулися з вашою проблемою, якщо ви відповісте на своє запитання, ви їм теж допоможете.
Майк Міллер

2
Оновлений документ для Java 8 тут
Ендрю Джонстон,

@Mauren: Чи можете ви надати посилання на своє закрите запитання, на яке ви самі відповіли? Це, можливо, варто обговорити на Meta.
кевінарпе

Відповіді:


290

Відповідну документацію можна знайти тут:

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.rmi.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 на локальній машині, це не має значення.

Оновлення :

У деяких випадках мені не вдалося дістатися до сервера. Потім це було виправлено, якщо я також встановив цей параметр:-Djava.rmi.server.hostname=127.0.0.1


9
The -Dcom.sun.management.jmxremote.local.only = false потрібна і зараз у
Centos

1
Nit pick: Для мене це дивно, що com.sun.management.jmxremoteмає значення за замовчуванням як true. (Дякую, Sun!) Щоб бути надзвичайно зрозумілим, особливо тим, хто менш знайомий з JMX nobs, я використовую: com.sun.management.jmxremote=trueRef: docs.oracle.com/javase/8/docs/technotes/guides/management/…
kevinarpe

1
"-Djava.rmi.server.hostname" працював як шарм для мене!
Орхун Д.

1
встановлення імені хоста для localhost дуже важливо, якщо ви намагаєтесь підключити a до віддаленого сервера через тунель SSH, що є дуже поширеним випадком.
Nikhil Owalekar

1
Це працює лише в тому випадку, якщо я відключив брандмауер на сервері. Я відкрив порт 9010 / tcp в цьому прикладі, звичайно, я також намагався додати Dcom.sun.management.jmxremote.rmi.port=9011і відкрити в брандмауері - все ще не можу з'єднатися з брандмауером, що працює. Будь-які думки? Я щось пропустив?
Кармагедон

70

Біг у контейнері 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 Ports

Схоже, що JMX також вимагає доступу до інтерфейсу віддаленого управління ( jstat ), який використовує інший порт для передачі деяких даних при арбітражі з'єднання. Я не побачив ніде відразу очевидного, jconsoleщоб встановити це значення. У пов'язаній статті процес був таким:

  • Спробуйте підключитися з, jconsoleякщо ввімкнено ведення журналу
  • Збій
  • З’ясуйте, який порт jconsoleнамагався використати
  • Використовуйте iptables/ firewallправила, якщо потрібно, щоб дозволити цей порт підключитися

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

Додати віддалений хост

Потім клацніть правою кнопкою миші нове підключення до віддаленого хоста та Add JMX Connection...

Додати з'єднання JMX

Не забудьте встановити прапорець Do not require SSL connection. Будемо сподіватися, що це дозволить вам підключитися.


-Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.rmi.port=[...]також є ключовим у випадку тунелювання JMX / RMI через SSH. Без них доступ до віддалених об'єктів здійснюється за допомогою загальнодоступного / основного / ... IP-сервера за допомогою якогось випадкового порту, який неможливо легко переслати.
Торстен

1
Я можу підтвердити, що вам дійсно потрібно використовувати зовнішній для контейнера IP. Наприклад, це не працює-Djava.rmi.server.hostname=0.0.0.0
рейдеркостін

Мені не потрібно було DOCKER_HOST_IPніде користуватися - я просто використовував localhostі пересилав порти під час запуску докерного зображення: -p 9998:9998, -p 9999:9999і т. Д.
Барні

9

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

Якщо це доступно для вас, також врахуйте jvisualvm, оскільки він надає велику кількість інформації про запущені процеси, включаючи профілер.


3
Це працює лише в тому випадку, якщо ви використовуєте jconsole на тому ж хості, що і JVM, який ви намагаєтеся контролювати.
Сірий

1
@ Thorbjorn Якщо я запускаю свою програму java без будь-яких параметрів і намагаюся з'єднатись з jconsole, я бачу в своїй програмі список, але коли я намагаюся підключити її не вдається. Я думаю, це через відсутність сертифікатів SSL. Я просто хотів побачити демонстрацію, тому мені довелося використовувати параметри, вказані у відповіді користувачем3013578, і це працювало для мене (JDK 1.7, Windows 8.1, 64 біт).
Капітан Джек Горобець

2
API прикріплення вимагає, щоб jconsole мав той самий 32/64 бітовий JVM, що і запущена програма на деяких платформах.
Thorbjørn Ravn Andersen

1
Чи можна відключити таку поведінку?
кевінарпе

7

Я використовую WAS ND 7.0

Моєму 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

Так, ваша відповідь спрацювала на мене (JDK 1.7, Windows 8.1 64 біт)
Капітан Джек Горобець

6

У Linux я використовував такі парами:

-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)


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 = false, якщо ви не хочете встановлювати цифрові сертифікати на хості jmx.

Якщо ви запустили свою програму на машині з IP-адресою 192.168.0.1 , відкрийте jconsole , поставте 192.168.0.1:8855 у поле Віддалений процес і натисніть кнопку Підключити .


Яка очікувана поведінка, якщо ви забудете -Dcom.sun.management.jmxremote.ssl=false? Якщо має jconsoleвідображатись помилка, чи це просто тихо не вдалося підключитися?
amacleod

2

поряд із наведеними нижче параметрами командного рядка,

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

Іноді на Linux-серверах imx-з'єднання не вдається. це тому, що в хмарі Linux Linux, в / etc / hosts, так що ім'я хоста вирішується на адресу хоста.

найкращий спосіб виправити це - пінг конкретного сервера Linux з іншої машини в мережі та використання IP-адреси цього хоста в

-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.

Але ніколи не покладайтеся на ipaddress, який ви отримуєте з сервера Linux, використовуючи ifconfig.me. ip, який ви потрапляєте туди, маскується, який присутній у файлі хоста.


1

Спершу потрібно перевірити, чи ваш процес Java вже працює з параметрами JMX. Зробити це:

ps -ef | grep java

Перевірте свій процес Java, який потрібно контролювати. Якщо ви можете побачити параметр jmx rmi Djmx.rmi.registry.port = xxxx, тоді використовуйте порт, згаданий тут, у вашому java visualvm, щоб віддалено підключити його під з'єднання jmx.

Якщо він не працює через jmx rmi-порт, тоді вам потрібно запустити процес java із наведеними нижче параметрами:

-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

Примітка: номери портів залежать від вашого вибору.

Тепер ви можете використовувати цей порт для спільного отримання jmx. Ось це порт 1234.


Якщо ви зможете побачити порт 1234, який використовується jmx, коли ви запускаєте це? sudo lsof -i:1234не показує нічого для мене
Gorgon_Union

1

Крок 1: Запустіть додаток, використовуючи наступні параметри.

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

Вище наведені аргументи прив'язують додаток до порту 9999.

Крок 2: Запустіть jconsole, виконавши команду jconsole в командному рядку або терміналі.

Виберіть "Віддалений процес:" та введіть URL-адресу як {IP_Address}: 9999 та натисніть кнопку Connect, щоб підключитися до віддаленої програми.

Ви можете посилатися на це посилання для повного застосування.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.