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:1088
pomocą jconsole lub jvisualvm. Ale nie mogę się połączyć przy użyciu xxx.xxx.xxx.xxx:1088
komputera zdalnego.
Nie ma zapory między serwerami ani w systemie operacyjnym. Ale aby wyeliminować tę możliwość, ja telnet xxx.xxx.xxx.xxx 1088
i 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.
Odpowiedzi:
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źródło
hostname -i
szczegółach: stackoverflow.com/a/11654322/99834 .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/hosts
plik.Oto polecenie potrzebne do włączenia JMX nawet z zewnątrz
Gdzie, jak założyłeś, myserver.example.com musi pasować do tego, co
hostname -i
zwraca.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.
źródło
java.rmi.server.hostname=<Public DNS name from AWS EC2 console for the instance>
. Mam nadzieję, że to komuś pomoże.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ę.
Zobacz także Dlaczego Java otwiera 3 porty po skonfigurowaniu JMX?
źródło
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ą
tak, aby kody RMI wysyłane do klienta zawierały publiczny adres serwera, umożliwiając klientom dostęp do niego z zewnątrz.
źródło
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ń:
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:
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”.
źródło
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
To jest moja konfiguracja:
źródło
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
źródło
Wiem, że ten wątek jest dość stary, ale jest dodatkowa opcja, która bardzo pomoże. Zobacz tutaj: https://realjenius.com/2012/11/21/java7-jmx-tunneling-freedom/
-Dcom.sun.management.jmxremote.rmi.port=1099
źródło
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.
źródło
Aby włączyć zdalne JMX, przekaż poniżej parametry maszyny wirtualnej wraz z poleceniem JAVA.
źródło
Spróbuj tego, przetestowałem, aby uzyskać dostęp do JMX w kontenerze docker
Następnie
$ jconsole localhost: 16000
źródło
Spróbuj użyć portów wyższych niż 3000.
źródło