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.

tuler
źródło
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
takete.dk
źródło
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.

sorin
źródło
Dodanie -Djava.rmi.server.hostname = myserver.example.com załatwiło sprawę! Dzięki!
Jim Bethancourt
Pozwoliłem
Klara,
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?

LeslieM
źródło
12

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

Jeśli próbujesz uzyskać dostęp do serwera, który jest za NAT - najprawdopodobniej będziesz musiał uruchomić serwer z opcją

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

tak, aby kody RMI wysyłane do klienta zawierały publiczny adres serwera, umożliwiając klientom dostęp do niego z zewnątrz.

h0nIg
źródło
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”.

yohann.martineau
źródło
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
Maoz Sadok
źródło
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

user3406690
źródło
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.

ianpojman
źródło
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
Ajay Kumar
źródło
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

Emmerson
źródło
-11

Spróbuj użyć portów wyższych niż 3000.

darko.topolsek
źródło