Zdalne połączenie JMX


97

Próbuję otworzyć połączenie JMX do aplikacji Java uruchomionej na komputerze zdalnym.

Aplikacja JVM jest skonfigurowana z następującymi opcjami:

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

Jestem w stanie połączyć się za localhost:1088pomocą jconsole lub jvisualvm. Ale nie mogę się połączyć przy użyciu xxx.xxx.xxx.xxx:1088komputera zdalnego.

Nie ma zapory między serwerami ani w systemie operacyjnym. Ale aby wyeliminować tę możliwość, ja telnet xxx.xxx.xxx.xxx 1088i myślę, że łączy się, ponieważ ekran konsoli staje się pusty.

Oba serwery to Windows Server 2008 x64. Próbowano z 64-bitową maszyną JVM i 32-bitową, ale żadne z nich nie działa.


1
Prawdopodobnie związane ze stackoverflow.com/questions/151238/…
tuler

Oto szczegółowy przewodnik stackoverflow.com/a/11654322/99834
sorin

Odpowiedzi:


118

Gdyby to było w Linuksie, problem polegałby na tym, że localhost jest interfejsem zwrotnym , potrzebujesz aplikacji, aby powiązać się z interfejsem sieciowym .

Możesz użyć netstat, aby potwierdzić, że nie jest powiązany z oczekiwanym interfejsem sieciowym.

Możesz to zrobić, wywołując program z parametrem systemowym java.rmi.server.hostname="YOUR_IP", jako zmienną środowiskową lub używając

java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP

7
Nie zapomnij o hostname -iszczegółach: stackoverflow.com/a/11654322/99834 .
sorin

Pracowałem! W naszym środowisku korzystamy z maszyn wirtualnych VMWare. Serwer znajdował się na maszynie wirtualnej. Maszyna wirtualna została wdrożona jako ogrodzona, więc ma wewnętrzne i zewnętrzne adresy IP. Rozpoczęliśmy proces Java serwera od -Djava.rmi.server.hostname = <external-ip-address>.
buzz3791

Aby ustawić adres IP hosta lub zmienić adres IP lokalnego hosta, ten link będzie przydatny.
Reza Ameri

Mam tutaj dwa pytania - 1) A co jeśli ktoś chce używać JMXMP zamiast JMX. Jakie byłyby do tego konfiguracje? oraz 2) Czy można nawiązać połączenie JMX bez ładowania protokołu RMI?
Kumar Vaibhav

64

Spędziłem ponad dzień próbując zmusić JMX do pracy spoza lokalnego hosta. Wygląda na to, że SUN / Oracle nie przedstawił dobrej dokumentacji na ten temat.

Upewnij się, że poniższe polecenie zwraca prawdziwy adres IP lub NAZWĘ HOSTA. Jeśli zwróci coś takiego jak 127.0.0.1, 127.0.1.1 lub localhost, nie zadziała i będziesz musiał zaktualizować /etc/hostsplik.

hostname -i

Oto polecenie potrzebne do włączenia JMX nawet z zewnątrz

-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

Gdzie, jak założyłeś, myserver.example.com musi pasować do tego, co hostname -izwraca.

Oczywiście musisz mieć pewność, że zapora sieciowa Cię nie blokuje, ale jestem prawie pewien, że to nie jest Twój problem, ponieważ jest to ostatni parametr, który nie jest udokumentowany.


Dodanie -Djava.rmi.server.hostname = myserver.example.com załatwiło sprawę! Dzięki!
Jim Bethancourt


2
„Upewnij się, że poniższe polecenie zwróci prawdziwy adres IP lub NAZWĘ HOSTA. Jeśli zwróci coś takiego jak 127.0.0.1, 127.0.1.1 lub localhost, nie będzie działać i będziesz musiał zaktualizować plik / etc / hosts.” Co?
PedroD

1
Po prostu szybko nie java.rmi.server.hostname=<Public DNS name from AWS EC2 console for the instance>. Mam nadzieję, że to komuś pomoże.
Sonny

24

Podczas moich testów z Tomcat i Java 8 JVM otwierał efemeryczny port oprócz portu określonego dla JMX. Poniższy kod naprawił mnie; spróbuj, jeśli masz problemy z klientem JMX (np. VisualVM nie łączy się.

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

Zobacz także Dlaczego Java otwiera 3 porty po skonfigurowaniu JMX?



8

wydaje się, że twój końcowy cytat pojawia się za wcześnie. Powinien znajdować się po ostatnim parametrze.

Ta sztuczka zadziałała na mnie.

Zauważyłem coś interesującego: kiedy uruchamiam moją aplikację za pomocą następującego wiersza poleceń:

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

Jeśli spróbuję połączyć się z tym portem ze zdalnej maszyny za pomocą jconsole, połączenie TCP powiedzie się, niektóre dane są wymieniane między zdalną konsolą jconsole i lokalnym agentem jmx, na którym jest wdrożony mój komponent MBean, a następnie jconsole wyświetla komunikat o błędzie połączenia. Wykonałem przechwytywanie wireshark i pokazuje wymianę danych pochodzącą zarówno z agenta, jak i jconsole.

Zatem nie jest to problem z siecią, jeśli wykonam netstat -an z właściwością systemową java.rmi.server.hostname lub bez niej, mam następujące powiązania:

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

Oznacza to, że w obu przypadkach gniazdo utworzone na porcie 9999 akceptuje połączenia z dowolnego hosta pod dowolnym adresem.

Myślę, że zawartość tej właściwości systemowej jest używana gdzieś podczas połączenia i porównywana z rzeczywistym adresem IP używanym przez agenta do komunikacji z jconsole. A jeśli te adresy nie są zgodne, połączenie nie powiedzie się.

Nie miałem tego problemu podczas łączenia się z tego samego hosta za pomocą jconsole, tylko z prawdziwych fizycznych zdalnych hostów. Więc przypuszczam, że to sprawdzenie jest wykonywane tylko wtedy, gdy połączenie przychodzi z „zewnątrz”.


Co masz na myśli, mówiąc „Twój końcowy cytat pojawia się za wcześnie”? Mam ten sam problem, widzę, że nawiązywane jest połączenie TCP, ale ostatecznie jconsole twierdzi, że się nie udało.
tsuna

Nie wiem, o ile dobrze pamiętam, gdzieś była otwarta wycena, a tego cytatu nie było na końcu parametrów. Może to było w scenariuszu wsadowym, nie pamiętam. Ale muszę przyznać, że ta odpowiedź nie ma sensu w odniesieniu do pytania ... Może pytanie zostało zredagowane? Brak edytowanego powiadomienia pod pytaniem ... Nie wiem, przepraszam.
yohann.martineau

6

rzeczą, która działała dla mnie, było ustawienie / etc / hosts tak, aby wskazywała nazwę hosta na adres IP, a nie na interfejs sprzężenia zwrotnego, a następnie zrestartuj moją aplikację.

cat / etc / hosts

127.0.0.1      localhost.localdomain localhost
192.168.0.1    myservername

To jest moja konfiguracja:

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

5

Wielkie dzięki, działa tak:

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



0

Mam ten sam problem i zmieniam dowolną nazwę hosta, która pasuje do nazwy lokalnego hosta na 0.0.0.0, wydaje się, że po tym działa.


0

Aby włączyć zdalne JMX, przekaż poniżej parametry maszyny wirtualnej wraz z poleceniem 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
Czy możesz mi powiedzieć, dlaczego wiąże się z 0.0.0.0, a nie z konkretnym
Babu James

0

Spróbuj tego, przetestowałem, aby uzyskać dostęp do JMX w kontenerze docker

-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

Następnie

$ jconsole localhost: 16000


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.