Conexión JMX remota

96

Estoy intentando abrir una conexión JMX a una aplicación Java que se ejecuta en una máquina remota.

La aplicación JVM está configurada con las siguientes opciones:

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

Puedo conectarme localhost:1088usando jconsole o jvisualvm. Pero no puedo conectarme usando xxx.xxx.xxx.xxx:1088desde una máquina remota.

No hay firewall entre los servidores o en el sistema operativo. Pero para eliminar esta posibilidad, telnet xxx.xxx.xxx.xxx 1088creo que se conecta, ya que la pantalla de la consola se pone en blanco.

Ambos servidores son Windows Server 2008 x64. Probé con JVM de 64 bits y 32 bits, ninguno de los dos funciona.

tuler
fuente
1
Probablemente relacionado con stackoverflow.com/questions/151238/...
Tuler
Aquí hay una guía detallada stackoverflow.com/a/11654322/99834
sorin

Respuestas:

117

Si hubiera estado en Linux, el problema sería que localhost es la interfaz de loopback , necesita que la aplicación se vincule a su interfaz de red .

Puede utilizar netstat para confirmar que no está vinculado a la interfaz de red esperada.

Puede hacer que esto funcione invocando el programa con el parámetro del sistema java.rmi.server.hostname="YOUR_IP", ya sea como una variable de entorno o usando

java -Djava.rmi.server.hostname=YOUR_IP YOUR_APP
takete.dk
fuente
7
No se olvide hostname -i, consulte stackoverflow.com/a/11654322/99834 para obtener más detalles.
sorin
¡Trabajó! En nuestro entorno utilizamos máquinas virtuales VMWare. El servidor estaba en una máquina virtual. La máquina virtual se implementó cercada para que tenga direcciones IP internas y externas. Comenzamos el proceso java del servidor con -Djava.rmi.server.hostname = <external-ip-address>.
buzz3791
Para configurar la IP del host o cambiar la IP del host local, este enlace sería útil.
Reza Ameri
Tengo dos preguntas aquí: 1) ¿Qué pasa si uno quiere usar JMXMP en lugar de JMX? ¿Cuáles serían las configuraciones para eso? y 2) ¿Es posible realizar la conexión JMX sin cargar el protocolo RMI?
Kumar Vaibhav
64

He pasado más de un día tratando de hacer que JMX funcione desde fuera de localhost. Parece que SUN / Oracle no pudo proporcionar una buena documentación sobre esto.

Asegúrese de que el siguiente comando le devuelva una IP real o HOSTNAME. Si devuelve algo como 127.0.0.1, 127.0.1.1 o localhost, no funcionará y tendrá que actualizar el /etc/hostsarchivo.

hostname -i

Aquí está el comando necesario para habilitar JMX incluso desde fuera

-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

Donde, como asumiste, myserver.example.com debe coincidir con lo que hostname -i devuelve.

Obviamente, debe asegurarse de que el firewall no lo bloquee, pero estoy casi seguro de que este no es su problema, ya que el problema es el último parámetro que no está documentado.

sorin
fuente
¡Añadiendo -Djava.rmi.server.hostname = myserver.example.com funcionó! ¡Gracias!
Jim Bethancourt
Me tomé la libertad de abrir un error de documentos JDK para esto: bugs.openjdk.java.net/browse/JDK-8066405
Klara
2
"Asegúrese de que el siguiente comando le devuelva una IP real o HOSTNAME. Si devuelve algo como 127.0.0.1, 127.0.1.1 o localhost, no funcionará y tendrá que actualizar el archivo / etc / hosts". ¿Qué?
PedroD
1
Solo un rápido no, el java.rmi.server.hostname=<Public DNS name from AWS EC2 console for the instance>. Espero que esto ayude a alguien.
Sonny
24

En mis pruebas con Tomcat y Java 8, la JVM estaba abriendo un puerto efímero además del especificado para JMX. El siguiente código me arregló; Pruébelo si tiene problemas en los que su cliente JMX (por ejemplo, VisualVM no se conecta.

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

Consulte también ¿Por qué Java abre 3 puertos cuando JMX está configurado?

LeslieM
fuente
8

parece que su cita final llega demasiado pronto. Debería estar después del último parámetro.

Este truco funcionó para mí.

Noté algo interesante: cuando inicio mi aplicación usando la siguiente línea de comando:

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

Si trato de conectarme a este puerto desde una máquina remota usando jconsole, la conexión TCP se realiza correctamente, se intercambian algunos datos entre el jconsole remoto y el agente jmx local donde está implementado mi MBean, y luego, jconsole muestra un mensaje de error de conexión. Realicé una captura de wirehark y muestra el intercambio de datos proveniente tanto del agente como de jconsole.

Por lo tanto, esto no es un problema de red, si realizo un netstat -an con o sin la propiedad del sistema java.rmi.server.hostname, tengo los siguientes enlaces:

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

Significa que en ambos casos el socket creado en el puerto 9999 acepta conexiones desde cualquier host en cualquier dirección.

Creo que el contenido de esta propiedad del sistema se usa en algún lugar de la conexión y se compara con la dirección IP real que usa el agente para comunicarse con jconsole. Y si esas direcciones no coinciden, la conexión falla.

No tuve este problema al conectarme desde el mismo host usando jconsole, solo desde hosts remotos físicos reales. Entonces, supongo que esta verificación se realiza solo cuando la conexión proviene del "exterior".

yohann.martineau
fuente
¿Qué quiere decir con "su cita final llega demasiado pronto"? Tengo el mismo problema, veo que se está realizando la conexión TCP, pero finalmente jconsole afirma que no se pudo conectar.
tsuna
No sé, si no recuerdo mal, había una cita abierta en alguna parte y esta cita no estaba al final de los parámetros. Quizás estaba en un script por lotes, no lo recuerdo. Pero debo admitir que esta respuesta no tiene sentido con respecto a la pregunta ... ¿Quizás la pregunta ha sido editada? No hay notificación editada en la pregunta ... No lo sé, lo siento.
yohann.martineau
6

lo que me funcionó fue configurar / etc / hosts para que apunte el nombre de host a la ip y no a la interfaz de bucle invertido y luego reiniciar mi aplicación.

gato / etc / hosts

127.0.0.1      localhost.localdomain localhost
192.168.0.1    myservername

Esta es mi configuración:

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

Muchas gracias, funciona así:

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

Tengo el mismo problema y cambio cualquier nombre de host que coincida con el nombre de host local a 0.0.0.0, parece que funciona después de hacer eso.

ianpojman
fuente
0

Para habilitar el control remoto JMX, pase los siguientes parámetros de VM junto con el 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
fuente
1
¿Puede decirme por qué se vincula a 0.0.0.0 y no a una IP específica
Babu James
0

Pruebe esto, probé para acceder a JMX dentro del contenedor de la ventana acoplable

-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

Luego

$ jconsole localhost: 16000

Emmerson
fuente
-11

Intente usar puertos superiores a 3000.

darko.topolsek
fuente