Conexão JMX remota

96

Estou tentando abrir uma conexão JMX com um aplicativo java em execução em uma máquina remota.

O aplicativo JVM é configurado com as seguintes opções:

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

Consigo me conectar localhost:1088usando jconsole ou jvisualvm. Mas não consigo conectar usando xxx.xxx.xxx.xxx:1088de uma máquina remota.

Não há firewall entre os servidores ou no sistema operacional. Mas para eliminar essa possibilidade, eu telnet xxx.xxx.xxx.xxx 1088e eu acho que conectamos, pois a tela do console fica em branco.

Ambos os servidores são Windows Server 2008 x64. Tentei com JVM de 64 bits e 32 bits, nenhum dos dois funciona.

tuler
fonte
1
Provavelmente relacionado a stackoverflow.com/questions/151238/…
tuler
Aqui está o guia detalhado stackoverflow.com/a/11654322/99834
sorin

Respostas:

117

Se fosse no Linux, o problema seria que o localhost é a interface de loopback , você precisa do aplicativo para vincular à sua interface de rede .

Você pode usar o netstat para confirmar que ele não está vinculado à interface de rede esperada.

Você pode fazer isso funcionar chamando o programa com o parâmetro do sistema java.rmi.server.hostname="YOUR_IP", como uma variável de ambiente ou usando

java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP
takete.dk
fonte
7
Não se esqueça hostname -i, consulte stackoverflow.com/a/11654322/99834 para obter detalhes.
sorin
Funcionou! Em nosso ambiente, usamos máquinas virtuais VMWare. O servidor estava em uma VM. A VM foi implantada protegida por isso tem endereços IP internos e externos. Iniciamos o processo java do servidor com -Djava.rmi.server.hostname = <external-ip-address>.
buzz3791
Para definir o ip do host ou alterar o ip do host local, este link seria útil.
Reza Ameri
Tenho duas perguntas aqui - 1) E se alguém quiser usar JMXMP em vez de JMX. Quais seriam as configurações para isso? e 2) É possível fazer a conexão JMX sem carregar o protocolo RMI?
Kumar Vaibhav
64

Passei mais de um dia tentando fazer o JMX funcionar de fora do localhost. Parece que a SUN / Oracle falhou em fornecer uma boa documentação sobre isso.

Certifique-se de que o comando a seguir retorne um IP ou HOSTNAME real. Se retornar algo como 127.0.0.1, 127.0.1.1 ou localhost, ele não funcionará e você terá que atualizar o /etc/hostsarquivo.

hostname -i

Aqui está o comando necessário para habilitar JMX mesmo de fora

-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

Onde, como você supôs, myserver.example.com deve corresponder ao que hostname -iretorna.

Obviamente, você precisa ter certeza de que o firewall não está bloqueando você, mas tenho quase certeza de que não é o seu problema, sendo o problema o último parâmetro que não está documentado.

Sorin
fonte
Adicionar -Djava.rmi.server.hostname = myserver.example.com resolveu o problema! Obrigado!
Jim Bethancourt
Tomei a liberdade de abrir um JDK docs bugs para isso: bugs.openjdk.java.net/browse/JDK-8066405
Klara
2
"Certifique-se de que o seguinte comando retorne um IP real ou HOSTNAME. Se ele retornar algo como 127.0.0.1, 127.0.1.1 ou localhost, não funcionará e você terá que atualizar o arquivo / etc / hosts." O que?
PedroD
1
Apenas um rápido não, o java.rmi.server.hostname=<Public DNS name from AWS EC2 console for the instance>. Espero que isso ajude alguém.
Sonny
24

Em meus testes com Tomcat e Java 8, a JVM estava abrindo uma porta efêmera além da especificada para JMX. O código a seguir me consertou; experimente se estiver tendo problemas com o cliente JMX (por exemplo, VisualVM não está se conectando.

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

Veja também Por que o Java abre 3 portas quando o JMX é configurado?

LeslieM
fonte
12

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

Se você está tentando acessar um servidor que está atrás de um NAT - você provavelmente terá que iniciar o seu servidor com a opção

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

de forma que os stubs RMI enviados ao cliente contenham o endereço público do servidor, permitindo que ele seja alcançado pelos clientes de fora.

h0nIg
fonte
8

parece que sua citação final veio muito cedo. Deve estar após o último parâmetro.

Este truque funcionou para mim.

Notei algo interessante: quando inicio meu aplicativo usando a seguinte linha de comando:

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

Se eu tentar conectar a esta porta de uma máquina remota usando jconsole, a conexão TCP é bem-sucedida, alguns dados são trocados entre o jconsole remoto e o agente jmx local onde meu MBean está implantado e, em seguida, o jconsole exibe uma mensagem de erro de conexão. Eu executei uma captura do WireChark e mostra a troca de dados vinda do agente e do jconsole.

Portanto, este não é um problema de rede, se eu executar um netstat -an com ou sem a propriedade de sistema java.rmi.server.hostname, tenho as seguintes ligações:

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

Isso significa que em ambos os casos o soquete criado na porta 9999 aceita conexões de qualquer host em qualquer endereço.

Acho que o conteúdo desta propriedade do sistema é usado em algum lugar na conexão e comparado com o endereço IP real usado pelo agente para se comunicar com o jconsole. E se esses endereços não corresponderem, a conexão falhará.

Não tive esse problema ao conectar do mesmo host usando jconsole, apenas de hosts remotos físicos reais. Portanto, suponho que essa verificação seja feita apenas quando a conexão vier de "fora".

yohann.martineau
fonte
O que você quer dizer com "sua frase final vem muito cedo"? Eu tenho o mesmo problema, vejo a conexão TCP sendo feita, mas eventualmente jconsole afirma que falhou ao conectar.
tsuna de
Não sei, se bem me lembro, havia uma citação aberta em algum lugar e essa citação não estava no final dos parâmetros. Talvez tenha sido em um script de lote, não me lembro. Mas devo admitir que esta resposta não faz sentido em relação à pergunta ... Será que a pergunta foi editada? Nenhuma notificação editada sob a pergunta ... Não sei, desculpe.
yohann.martineau
6

a única coisa que funcionou para mim foi definir / etc / hosts para apontar o nome do host para o ip e não para a interface de loopback e então reiniciar meu aplicativo.

cat / etc / hosts

127.0.0.1      localhost.localdomain localhost
192.168.0.1    myservername

Esta é a minha configuração:

-Dcom.sun.management.jmxremote.port=1617 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false
Maoz Zadok
fonte
5

Muito obrigado, funciona assim:

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
fonte
0

Eu tenho o mesmo problema e mudo qualquer nome de host que corresponda ao nome do host local para 0.0.0.0, parece funcionar depois de fazer isso.

ianpojman
fonte
0

Para habilitar o JMX remoto, passe os parâmetros VM abaixo junto com o Comando 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
fonte
1
Você pode me dizer por que ele está vinculado a 0.0.0.0 e não a um IP específico
Babu James
0

Tente isso, eu testei para acessar JMX dentro do contêiner do 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

Então

$ jconsole localhost: 16000

Emmerson
fonte
-11

Tente usar portas superiores a 3000.

darko.topolsek
fonte