Удаленное соединение JMX

97

Я пытаюсь открыть JMX-соединение с Java-приложением, запущенным на удаленном компьютере.

В JVM приложения настроены следующие параметры:

  • com.sun.management.jmxremote
  • com.sun.management.jmxremote.port = 1088
  • com.sun.management.jmxremote.authenticate = false
  • com.sun.management.jmxremote.ssl = false

Я могу подключиться с localhost:1088помощью jconsole или jvisualvm. Но я не могу подключиться с xxx.xxx.xxx.xxx:1088удаленного компьютера.

Между серверами и ОС нет брандмауэра. Но чтобы исключить эту возможность, я telnet xxx.xxx.xxx.xxx 1088и я думаю, что он подключается, так как экран консоли гаснет.

Оба сервера - Windows Server 2008 x64. Пробовал с 64-битной JVM и 32-битной, ничего не работает.

тюлер
источник
1
Вероятно, связано с stackoverflow.com/questions/151238/…
tuler
Вот подробное руководство stackoverflow.com/a/11654322/99834
Sorin

Ответы:

118

Если бы это было в Linux, проблема заключалась бы в том, что localhost является интерфейсом обратной связи , вам нужно, чтобы приложение было привязано к вашему сетевому интерфейсу .

Вы можете использовать netstat, чтобы подтвердить, что он не привязан к ожидаемому сетевому интерфейсу.

Вы можете выполнить эту работу, вызвав программу с системным параметром java.rmi.server.hostname="YOUR_IP", либо как переменную среды, либо используя

java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP
takete.dk
источник
7
Не забывайте об этом hostname -i, подробнее см. Stackoverflow.com/a/11654322/99834 .
sorin
Работал! В нашей среде мы используем виртуальные машины VMWare. Сервер был на виртуальной машине. Виртуальная машина была развернута изолированной, поэтому у нее есть внутренний и внешний IP-адреса. Мы запустили серверный java-процесс с -Djava.rmi.server.hostname = <external-ip-address>.
buzz3791
Эта ссылка будет полезна для установки IP-адреса хоста или изменения IP-адреса локального хоста .
Реза Амери
У меня есть два вопроса: 1) Что делать, если кто-то хочет использовать JMXMP, а не JMX. Какие бы конфиги для этого? и 2) Можно ли установить соединение JMX без загрузки протокола RMI?
Кумар Вайбхав
64

Я потратил больше дня, пытаясь заставить JMX работать за пределами localhost. Похоже, что SUN / Oracle не смогли предоставить хорошую документацию по этому поводу.

Убедитесь, что следующая команда вернет вам реальный IP-адрес или HOSTNAME. Если он вернет что-то вроде 127.0.0.1, 127.0.1.1 или localhost, он не будет работать, и вам придется обновить /etc/hostsфайл.

hostname -i

Вот команда, необходимая для включения JMX даже извне

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.port=1100
-Djava.rmi.server.hostname=myserver.example.com

Где, как вы предполагали, myserver.example.com должен соответствовать тому, что hostname -iвозвращает.

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

Сорин
источник
Добавление -Djava.rmi.server.hostname = myserver.example.com сделало свое дело! Спасибо!
Джим Бетанкур,
Я взял на себя смелость открыть JDK docs с ошибками для этого: bugs.openjdk.java.net/browse/JDK-8066405
Клара
2
«Убедитесь, что следующая команда вернет вам настоящий IP-адрес или HOSTNAME. Если она вернет что-то вроде 127.0.0.1, 127.0.1.1 или localhost, она не будет работать, и вам придется обновить файл / etc / hosts». Какой?
PedroD
1
Просто быстро нет java.rmi.server.hostname=<Public DNS name from AWS EC2 console for the instance>. Надеюсь, это кому-то поможет.
Сонни,
24

В моем тестировании с Tomcat и Java 8 JVM открывала эфемерный порт в дополнение к тому, который указан для JMX. Следующий код исправил меня; попробуйте, если у вас возникли проблемы, когда ваш клиент JMX (например, VisualVM не подключается.

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

Также см. Почему Java открывает 3 порта при настройке JMX?

LeslieM
источник
12

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

Если вы пытаетесь получить доступ к серверу, который находится за NAT, вам, скорее всего, придется запустить свой сервер с опцией

-Djava.rmi.server.hostname=<public/NAT address>

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

h0nIg
источник
8

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

У меня этот трюк сработал.

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

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

Если я попытаюсь подключиться к этому порту с удаленного компьютера с помощью jconsole, TCP-соединение будет успешным, некоторые данные будут обмениваться между удаленной jconsole и локальным jmx-агентом, где развернут мой MBean, а затем jconsole отобразит сообщение об ошибке подключения. Я выполнил захват Wirehark, и он показывает, что обмен данными происходит как от агента, так и от jconsole.

Таким образом, это не проблема сети, если я выполняю netstat -an с системным свойством java.rmi.server.hostname или без него, у меня будут следующие привязки:

 TCP    0.0.0.0:9999           0.0.0.0:0              LISTENING
 TCP    [::]:9999              [::]:0                 LISTENING

Это означает, что в обоих случаях сокет, созданный на порту 9999, принимает соединения с любого хоста по любому адресу.

Я думаю, что содержимое этого системного свойства используется где-то при подключении и сравнивается с фактическим IP-адресом, используемым агентом для связи с jconsole. И если эти адреса не совпадают, соединение не устанавливается.

У меня не было этой проблемы при подключении с того же хоста с помощью jconsole, только с реальных физических удаленных хостов. Итак, я предполагаю, что эта проверка выполняется только тогда, когда соединение идет "извне".

Йоханн Мартино
источник
Что вы имеете в виду, говоря «ваша финальная цитата приходит слишком рано»? У меня та же проблема, я вижу, что устанавливается TCP-соединение, но в конечном итоге jconsole утверждает, что не удалось подключиться.
tsuna
Не знаю, если я правильно помню, где-то была открытая цитата, и этой цитаты не было в конце параметров. Может, это был пакетный сценарий, я не могу вспомнить. Но я должен признать, что этот ответ не имеет смысла относительно вопроса ... Может быть, вопрос отредактировали? Нет отредактированного уведомления под вопросом ... Не знаю, извините.
yohann.martineau
6

у меня сработало то, что я установил / etc / hosts, чтобы указать имя хоста на ip, а не на интерфейс обратной связи, а затем перезапустить мое приложение.

кошка / etc / hosts

127.0.0.1      localhost.localdomain localhost
192.168.0.1    myservername

Это моя конфигурация:

-Dcom.sun.management.jmxremote.port=1617 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false
Маоз Садок
источник
5

Большое спасибо, это работает так:

java -Djava.rmi.server.hostname = xxx.xxx.xxx.xxx -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl = false -Dcom.sun.management.jmxremote.authenticate = false - Dcom.sun.management.jmxremote.port = 25000 -jar myjar .jar

user3406690
источник
0

У меня такая же проблема, и я меняю любое имя хоста, которое соответствует имени локального хоста, на 0.0.0.0, после этого оно, похоже, работает.

Ианпойман
источник
0

Чтобы включить удаленный JMX, передайте параметры виртуальной машины вместе с командой JAVA.

    -Dcom.sun.management.jmxremote 
    -Dcom.sun.management.jmxremote.port=453
    -Dcom.sun.management.jmxremote.authenticate=false                               
    -Dcom.sun.management.jmxremote.ssl=false 
    -Djava.rmi.server.hostname=myDomain.in
Аджай Кумар
источник
1
Можете ли вы сказать мне, почему он привязан к 0.0.0.0, а не к конкретному IP?
Бабу Джеймс
0

Попробуйте это, я тестировал доступ к JMX внутри контейнера докеров

-Dcom.sun.management.jmxremote = true -Djava.rmi.server.hostname = localhost -Dcom.sun.management.jmxremote.port = 16000 -Dcom.sun.management.jmxremote.rmi.port = 16000 -Dcom.sun .management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote.ssl = false

затем

Локальный хост $ jconsole: 16000

Эммерсон
источник
-11

Попробуйте использовать порты выше 3000.

darko.topolsek
источник