Conexión remota JMX

Intento abrir una conexión JMX a la 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 usando localhost:1088 usando jconsole o jvisualvm. Pero no puedo conectarme usando xxx.xxx.xxx.xxx:1088 desde 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 1088 y creo que se conecta, ya que la pantalla de la consola se queda en blanco.

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

Si hubiera estado en Linux, el problema sería que localhost es la interfaz de bucle de retorno , necesita una aplicación para enlazar a su interfaz de red .

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

Puede hacer que esto funcione invocando el progtwig 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 

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/hosts .

 hostname -i 

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

 -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 suponía, myserver.example.com debe coincidir con el hostname -i devuelve hostname -i .

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.

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 solucionó; pruébelo si tiene problemas con su cliente JMX (p . ej., VisualVM no se está conectando).

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

También vea ¿Por qué Java abre 3 puertos cuando JMX está configurado?

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

Si está intentando acceder a un servidor que está detrás de un NAT, lo más probable es que tenga que iniciar su servidor con la opción

 -Djava.rmi.server.hostname= 

para que los resguardos RMI enviados al cliente contengan la dirección pública del servidor, lo que permite que los clientes lo puedan contactar desde el exterior.

Parece que tu cita final llega demasiado pronto. Debería ser después del último parámetro.

Este truco funcionó para mí.

Noté algo interesante: cuando comienzo 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 tiene éxito, algunos datos se intercambian entre jconsole remoto y el agente local de jmx donde se implementa mi MBean, y entonces, jconsole muestra un mensaje de error de conexión. Realicé una captura de wireshark, 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 propiedad de 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 utilizada por 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 hace solo cuando la conexión proviene del “exterior”.

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

Lo que más me funciona es configurar / etc / hosts para apuntar el nombre de host a la ip y no a la interfaz de loopback y luego reiniciar mi aplicación.

cat / 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 

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 hacerlo.

Para habilitar el control remoto JMX, pase debajo de los 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 

Intenta usar puertos de más de 3000.