У кого-нибудь когда-нибудь работала удаленная JMX JConsole?

120

Кажется, у меня никогда не было этого, чтобы работать раньше. В настоящее время Я ЗНАЮ, что это не работает.

Но мы запускаем наш Java-процесс:

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

Я могу подключиться к порту через telnet, и «что-то есть» (то есть, если я не запустил процесс, ничего не ответит, но если я это сделаю, то да), но я не могу заставить JConsole работать, заполняя IP и порт.

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

Кто-нибудь знает полезный совет по этому поводу?

Уилл Хартунг
источник
3
Если вы используете Tomcat, это может быть решением: stackoverflow.com/questions/1263991/…
Hajo Thelen
5
Вы что-то здесь забыли принять, @Will?
Грей

Ответы:

126

У меня есть решение для этого:

Если ваш процесс Java выполняется в Linux за брандмауэром, и вы хотите запустить JConsole / Java VisualVM / Java Mission Control в Windows на локальном компьютере, чтобы подключить его к порту JMX вашего процесса Java .

Вам нужен доступ к вашей Linux-машине через SSH-вход. Все коммуникации будут туннелироваться через соединение SSH.

СОВЕТ: Это решение работает независимо от того, есть брандмауэр или нет.

Недостаток: каждый раз, когда вы перезапускаете свой Java-процесс, вам нужно будет снова выполнять все шаги с 4 по 9.


1. Вам понадобится набор шпатлевок для вашей машины с Windows отсюда:

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

По крайней мере, putty.exe


2. Определите один свободный порт на вашем компьютере с Linux:

<jmx-remote-port>

Пример:

jmx-remote-port = 15666      


3. Добавьте аргументы в java-процесс на Linux-машине.

Делать это нужно именно так. Если это сделано, как показано ниже, это работает для машин Linux за брандмауэрами (это работает по причине -Djava.rmi.server.hostname=localhostаргумента).

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=<jmx-remote-port>
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

Пример:

java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=15666 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=localhost ch.sushicutta.jmxremote.Main


4. Получите идентификатор процесса Java.

ps -ef | grep <java-processname>

result ---> <process-id>

Пример:

ps -ef | grep ch.sushicutta.jmxremote.Main

result ---> 24321


5. Найдите произвольный порт для загрузки заглушек RMIServer.

Java-процесс открывает новый TCP-порт на Linux-машине, где RMI Server-Stubs будут доступны для загрузки. Этот порт также должен быть доступен через туннель SSH для подключения к виртуальной машине Java.

С netstat -lpэтим портом также можно найти lsof -iподсказки, какой порт был открыт из java-процесса.

ПРИМЕЧАНИЕ. Этот порт всегда изменяется при запуске Java-процесса.

netstat -lp | grep <process-id>

tcp        0      0 *:<jmx-remote-port>     *:*     LISTEN      24321/java
tcp        0      0 *:<rmi-server-port>     *:*     LISTEN      24321/java


result ---> <rmi-server-port>

Пример:

netstat -lp | grep 24321

tcp        0      0 *:15666     *:*     LISTEN      24321/java
tcp        0      0 *:37123     *:*     LISTEN      24321/java


result ---> 37123


6. Включите два SSH-туннеля на вашем компьютере с Windows с помощью putty.

Source port: <jmx-remote-port>
Destination: localhost:<jmx-remote-port>
[x] Local       
[x] Auto       

Source port: <rmi-server-port>
Destination: localhost:<rmi-server-port>
[x] Local       
[x] Auto

Пример:

Source port: 15666
Destination: localhost:15666
[x] Local       
[x] Auto       

Source port: 37123
Destination: localhost:37123
[x] Local       
[x] Auto


Настройки открытия SSL-туннеля через Putty


7. Войдите в свою Linux-машину с помощью Putty с включенным SSH-туннелем.

Оставьте шпатлевку открытой.

Когда вы вошли в систему, Putty будет туннелировать все TCP-соединения с Linux-машиной через SSH-порт 22.

JMX-порт:

Windows machine: localhost:15666   >>> SSH >>>   linux machine: localhost:15666

RMIServer-Сто-порт:

Windows Machine: localhost:37123   >>> SSH >>>   linux machine: localhost:37123


8. Запустите JConsole / Java VisualVM / Java Mission Control, чтобы подключиться к вашему Java-процессу, используя следующий URL-адрес.

Это работает, потому что JConsole / Java VisualVM / Java Mission Control думает, что вы подключаетесь к порту на локальной машине Windows. но Putty отправляет всю полезную нагрузку на порт 15666 на вашу Linux-машину.

На Linux-машине сначала процесс java дает ответ и отправляет обратно порт RMIServer. В этом примере 37123.

Затем JConsole / Java VisualVM / Java Mission Control считает, что он подключается к localhost: 37123, и putty отправит всю полезную нагрузку на Linux-машину.

Процесс java отвечает, и соединение открыто.

[x] Remote Process:
service:jmx:rmi:///jndi/rmi://localhost:<jndi-remote-port>/jmxrmi

Пример:

[x] Remote Process:
service:jmx:rmi:///jndi/rmi://localhost:15666/jmxrmi


Подключиться через URL-адрес службы jmx


9. НАСЛАЖДАЙТЕСЬ № 8-]

sushicutta
источник
1
Небольшой вопрос - невозможно установить JMX-соединение без rmi?
Кумар Вайбхав
5
Я получил подсказку, что мы можем установить для rmi.port фиксированный номер порта, чтобы мы могли установить произвольный порт для загрузки заглушек RMIServer. это должно работать со свойством Java "com.sun.management.jmxremote.rmi.port = <rmi-server-port>". Это похоже на недокументированную функцию в Oracle Java VM.
sushicutta
1
Конечно, лучше, чем настраивать хранилища ключей и доверенные хранилища,
TekiusFanatikus
Тот же процесс, но у меня нет такого объекта в таблице
wener
2
@sushicutta, можете ли вы добавить этот совет в свой ответ, он работает отлично и может удалить шаги с 4 по 6, уловка в том, что ваш перенаправленный порт должен быть таким же, как исходный порт, и оба порта jmx и rmi также должны будь таким же
потрепанным
80

Добавление -Djava.rmi.server.hostname='<host ip>'решило эту проблему для меня.

эпоха
источник
2
В моем случае мне нужно добавить IP-адрес (-Djava.rmi.server.hostname = <ip>). hostname -i дал мне два IP-адреса, и правильный был вторым в списке.
Георгий Болюба
4
не решил проблему для меня. подключение windows-2-windows не является проблемой для меня, НО когда я пытаюсь подключиться с JVM Jvisualvm.exe в Windows для мониторинга java-службы, запущенной в SUSE с Oracle JDK 1.6.024, соединение не устанавливается. По этой причине я думаю, что этот вопрос до сих пор остается без ответа.
djangofan
Это решило проблему для меня. Это плюс обычный набор 3 (аутентификация / порт / ssl), и теперь я могу удаленно подключиться. Коробка прослушивает несколько виртуальных интерфейсов, возможно, почему не указание хоста запутало jvm.
Nicholi
Наконец-то решил мои проблемы с подключением jconsole на моем ноутбуке с osx. Спасибо.
rado
Работал у меня. Спасибо!
Джефф
58

Пробовал с Java 8 и более новыми версиями

Это решение хорошо работает также с межсетевыми экранами.

1. Добавьте это в свой сценарий запуска java на удаленном хосте:

-Dcom.sun.management.jmxremote.port=1616
-Dcom.sun.management.jmxremote.rmi.port=1616
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

2. Выполните это на своем компьютере.

  • Пользователи Windows :

    putty.exe -ssh user@remote-host -L 1616:remote-host:1616

  • Пользователи Linux и Mac :

    ssh user@remote-host -L 1616:remote-host:1616

3. Запустите jconsoleна своем компьютере.

jconsole localhost:1616

4. Удачи!

PS: на шаге 2 с помощью sshи -Lвы указываете, что порт 1616 на локальном (клиентском) хосте должен быть перенаправлен на удаленную сторону. Это туннель ssh, который помогает избежать проблем с брандмауэрами или различными сетевыми проблемами.

freedev
источник
1
ЗДОРОВО!! Пытался в течение 6 + часов использовать jmx-remote для экземпляра ActiveMQ на java8. НАКОНЕЦ ЧТО-ТО Сработало !! Спасибо! :)
Rop
Спасибо, как и вы, я тоже боролся около дня, и после такой большой работы я просто подумал: «Я должен написать это ТАК !!»
freedev 05
2
На самом деле отстой, что Oracle не упоминает "com.sun.management.jmxremote.rmi.port", "java.rmi.server.hostname" docs.oracle.com/javase/8/docs/technotes/guides/management/… I думаю, это была моя проблема.
Rop
Потому что, AFAIK, эта проблема не в JMX, а в том, как работает RMI. Например, после этого случая у меня была та же проблема с jmeter, который использует rmi в своей реализации клиент / сервер.
freedev 05
2
Оно работает. Просто добавлю свой опыт работы с туннелями: 1) можно использовать "localhost" в "-L 1616: localhost: 1616" 2) нельзя изменить исходный порт, т.е. это не сработает: "-L 9999: localhost: 1616"
gargii
19

Вероятно, у вас проблема с брандмауэром. «Проблема» в том, что указанный вами порт - не единственный используемый порт, он использует еще 1 или, может быть, 2 порта для RMI, и они, вероятно, заблокированы брандмауэром.

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

Существует решение, которое не требует открытия большого количества портов, однако я заставил его работать, используя объединенные исходные фрагменты и советы от

http://forums.sun.com/thread.jspa?threadID=5267091 - ссылка больше не работает

http://blogs.oracle.com/jmxetc/entry/connecting_through_firewall_using_jmx

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

Можно даже настроить ssh-туннель и заставить его работать :-)

Саймон Гроенвольт
источник
2
Мне удалось обойти брандмауэр, используя только псевдоним, описанный в simplegenius.com/2010/08/jconsole-via-socks-ssh-tunnel.html вместе с настройкой -Djava.rmi.server.hostname, как указано в другом ответе здесь.
Дэмиен
Примечание для будущих читателей: ссылка не forums.sun.comработает
CDspace 02
1
На заметку будущим читателям: ссылка не blogs.oracle.comработает.
Grimlock
17

После тестирования моего Google-fu в течение последних нескольких дней я наконец смог заставить это работать после компиляции ответов из Stack Overflow и этой страницы http://help.boomi.com/atomsphere/GUID-F787998C- 53C8-4662-AA06-8B1D32F9D55B.html .

Репост со страницы Dell Boomi:

To Enable Remote JMX on an Atom

If you want to monitor the status of an Atom, you need to turn on Remote JMX (Java Management Extensions) for the Atom.

Use a text editor to open the <atom_installation_directory>\bin\atom.vmoptions file.

Add the following lines to the file:

-Dcom.sun.management.jmxremote.port=5002
-Dcom.sun.management.jmxremote.rmi.port=5002
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

Единственная строка, которую я не видел ни одной обложки ответа на переполнение стека, - это

-Dcom.sun.management.jmxremote.rmi.port=5002

В моем случае я пытался получить показатели Kakfa, поэтому я просто изменил вышеуказанный параметр, чтобы он соответствовал -Dcom.sun.management.jmxremote.portзначению. Итак, без какой-либо аутентификации минимальная конфигурация должна выглядеть так:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=(jmx remote port)

-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=(jmx remote port)
-Djava.rmi.server.hostname=(CNAME|IP Address)
Sergio
источник
1
Плюс один для "Google-fu"
kevinarpe
com.sun.management.jmxremote.rmi.port также был ключевым для меня. См. Также этот ответ: stackoverflow.com/a/22306586/123205
Дэвид
Мне не нужен "com.sun.management.jmxremote.local.only", поэтому я не думаю, что ваша конфигурация действительно "минимум"
Дэвид
7

Шаги 4-7 Сушикутты можно пропустить, добавив к шагу 3 следующую строку:

-Dcom.sun.management.jmxremote.rmi.port=<same port as jmx-remote-port>

например, Добавить к параметрам запуска:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.rmi.port=12345
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

Для переадресации портов подключитесь, используя:

ssh -L 12345:localhost:12345 <username>@<host>

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

ssh -L 12345:localhost:12345 <username>@<host2>

Помните, что hostname = localhost необходимо, чтобы убедиться, что jmxremote сообщает rmi-соединению использовать туннель. В противном случае он может попытаться подключиться напрямую и попасть в брандмауэр.

user2412906
источник
Этот метод помогает мне: (1) Я добавляю пропущенные параметры JMX и перезапускаю приложение (2) Затем запускаю ssh -L <JMX_port>:localhost:<JMX_port> <remote_user>@<remote_host> на локальном компьютере (3) Затем я подключаюсь к удаленному JMX, используя: jconsole <remote_host>:<JMX_port>
Rib47
6

PROTIP:

Порт RMI открывается на произвольном порте. Если у вас есть брандмауэр и вы не хотите открывать порты 1024-65535 (или использовать vpn), вам необходимо сделать следующее.

Вам необходимо исправить (как при наличии известного номера) порты реестра RMI и JMX / RMI Server. Вы делаете это, помещая jar-файл (catalina-jmx-remote.jar в дополнительный) в lib-dir и настраивая специальный слушатель на сервере:

<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
      rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />

(И, конечно же, обычные флаги для активации JMX

    -Dcom.sun.management.jmxremote  \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Djava.rmi.server.hostname=<HOSTNAME> \

См .: Удаленный прослушиватель жизненного цикла JMX на http://tomcat.apache.org/tomcat-6.0-doc/config/listeners.html

Затем вы можете подключиться, используя этот ужасный URL:

service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>:10001/jmxrmi
supdog
источник
Пробовал вышеуказанный с дополнительным jar и может видеть, что порты RMI прослушивают, как указано, но случайные порты все еще используются RMI после подключения к порту JVM с помощью VisualVM. Обходной путь: следите за портами с помощью lsof -i и открывайте те, соединения с которыми заблокированы.
Джозеф Ласт
5

Убедитесь, что ваш сервер находится за брандмауэром. JMX основан на RMI, который при запуске открывает два порта. Один из них - порт регистра, по умолчанию - 1099, и его можно указать в com.sun.management.jmxremote.portопции. Другой - для передачи данных и является случайным, что и является причиной проблемы. Хорошей новостью является то, что в JDK6 этот случайный порт можно указать с помощью com.sun.management.jmxremote.rmi.portопции.

export CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8991 -Dcom.sun.management.jmxremote.rmi.port=8991 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
arganzheng
источник
4

Получить JMX через брандмауэр действительно сложно. Проблема в том, что стандартный RMI использует второй случайно назначенный порт (рядом с реестром RMI).

У нас есть три эффективных решения, но для каждого случая нужно другое:

  1. JMX через SSH-туннель с прокси-сервером Socks, использует стандартный RMI с магией SSH http://simplygenius.com/2010/08/jconsole-via-socks-ssh-tunnel.html

  2. JMX MP (альтернатива стандартному RMI), использует только один фиксированный порт, но требует специального jar на сервере и клиенте http://meteatamel.wordpress.com/2012/02/13/jmx-rmi-vs-jmxmp/

  3. Запустите код формы JMX Server, там можно использовать стандартный RMI и использовать фиксированный второй порт: https://issues.apache.org/bugzilla/show_bug.cgi?id=39055

user85155
источник
Все остальные ответы должны быть дополнением к этому
ruruskyi 03
2

При тестировании / отладке / диагностике удаленных проблем JMX сначала всегда пытайтесь подключиться к тому же хосту, который содержит MBeanServer (то есть localhost), чтобы исключить сетевые и другие проблемы, не связанные с JMX.

eljenso
источник
2

Здесь уже есть несколько отличных ответов, но есть несколько более простой подход, которым, я думаю, стоит поделиться.

Подход sushicutta хорош, но очень ручной, поскольку вам нужно каждый раз получать порт RMI. К счастью, мы можем обойти это, используя прокси-сервер SOCKS вместо того, чтобы явно открывать туннели портов. Обратной стороной этого подхода является то, что приложение JMX, которое вы запускаете на своем компьютере, должно быть настроено для использования прокси. Большинство процессов вы можете сделать это, добавив свойства java, но некоторые приложения не поддерживают это.

шаги:

  1. Добавьте параметры JMX в сценарий запуска для удаленной службы Java:

    -Dcom.sun.management.jmxremote=true
    -Dcom.sun.management.jmxremote.port=8090
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.authenticate=false
    
  2. Настройте прокси-соединение SOCKS с удаленным компьютером:

    ssh -D 9696 user@remotemachine.com
    
  3. Настройте локальное приложение для мониторинга Java на использование прокси-сервера SOCKS (localhost: 9696). Примечание. Иногда это можно сделать из командной строки, например:

    jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=9696
    
Richs
источник
2

У меня сработало следующее (хотя я думаю, что порт 2101 на самом деле этому не способствовал):

-Dcom.sun.management.jmxremote.port=2100
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=2101
-Djava.rmi.server.hostname=<IP_ADDRESS>OR<HOSTNAME>

Я подключаюсь с удаленного компьютера к серверу, на котором работает Docker, а процесс находится внутри контейнера. Кроме того, я остановил firewallD, но я не думаю, что это была проблема, поскольку я мог подключиться к 2100 даже при открытом брандмауэре. Надеюсь, поможет.

И я.
источник
1

Я запускаю JConsole / JVisualVm на подключении Windows к tomcat под управлением Linux Redhat ES3.

Отключение фильтрации пакетов с помощью следующей команды помогло мне:

/usr/sbin/iptables -I INPUT -s jconsole-host -p tcp --destination-port jmxremote-port -j ACCEPT

где jconsole-host - это либо имя хоста, либо адрес хоста, на котором работает JConsole, а jmxremote-port - это номер порта, установленный для com.sun.management.jmxremote.port для удаленного управления.

Кишор
источник
2
у меня не сработало на инстансе SUSE Amazon EC2. Я думаю, проблема в другом.
djangofan
1

Я использую boot2docker для запуска контейнеров докеров с Tomcat внутри, и у меня такая же проблема, решение заключалось в следующем:

  • Добавить -Djava.rmi.server.hostname=192.168.59.103
  • Используйте один и тот же порт JMX в хост и Докер контейнере, например: docker run ... -p 9999:9999 .... Использование разных портов не работает.
smallo
источник
0

Вам также необходимо убедиться, что имя вашего компьютера соответствует IP-адресу, к которому привязан JMX; НЕ localhost и не 127.0.0.1. Для меня это помогло добавить запись в хосты, которая явно определяет это.

Джозеф
источник
0

Получить JMX через брандмауэр совсем не сложно. Есть одна маленькая загвоздка. Вы должны перенаправить оба настроенного порта JMX, т.е. 9010 и один из динамических портов, который он прослушивает на моей машине, был> 30000

Лукаш
источник
0

Вот шаги, которые сработали для меня (debian за брандмауэром на стороне сервера, доступ через VPN с моего локального Mac):

проверьте ip сервера

hostname -i

используйте параметры JVM:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=[jmx port]
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=[server ip from step 1]

запустить приложение

найти pid запущенного java-процесса

проверьте все порты, используемые JMX / RMI

netstat -lp | grep [pid from step 4]

откройте все порты с шага 5 на брандмауэре

Вуаля.

Мариуш
источник
0

Чтобы внести свой вклад, это то, что я сделал в CentOS 6.4 для Tomcat 6.

  1. Завершение работы службы iptables

    service iptables stop
    
  2. Добавьте следующую строку в tomcat6.conf

    CATALINA_OPTS="${CATALINA_OPTS} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8085 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=[host_ip]"
    

Таким образом, я смог подключиться с другого ПК с помощью JConsole.

Андрес С.
источник
0

Я пытаюсь JMC запустить Flight Recorder (JFR) для профилирования NiFi на удаленном сервере, который не предлагает графическую среду для запуска JMC.

Основываясь на других ответах, приведенных здесь, и после многих проб и ошибок, вот что я предоставляю JVM ( conf / bootstrap.conf ) при запуске NiFi:

java.arg.90=-Dcom.sun.management.jmxremote=true
java.arg.91=-Dcom.sun.management.jmxremote.port=9098
java.arg.92=-Dcom.sun.management.jmxremote.rmi.port=9098
java.arg.93=-Dcom.sun.management.jmxremote.authenticate=false
java.arg.94=-Dcom.sun.management.jmxremote.ssl=false
java.arg.95=-Dcom.sun.management.jmxremote.local.only=false
java.arg.96=-Djava.rmi.server.hostname=10.10.10.92  (the IP address of my server running NiFi)

Я положил это в / etc / hosts , хотя сомневаюсь, что это нужно:

10.10.10.92   localhost

Затем, после запуска JMC, я создаю удаленное соединение со следующими свойствами:

Host: 10.10.10.92
Port: 9098
User: (nothing)
Password: (ibid)

Кстати, если я щелкну URL-адрес пользовательской службы JMX, я вижу:

service:jmx:rmi:///jndi/rmi://10.10.10.92:9098/jmxrmi

Это наконец сделало это за меня.

Расс Бейтман
источник