java - remote - ¿Cómo activar JMX en mi JVM para acceder con jconsole?
jconsole vs visualvm (7)
¿Cómo activar JMX en una JVM para acceder con jconsole?
Correr en un contenedor Docker introdujo una gran cantidad de problemas adicionales para conectar, así que con suerte esto ayuda a alguien. Terminé necesitando agregar las siguientes opciones que explicaré a continuación:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=${DOCKER_HOST_IP}
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9998
DOCKER_HOST_IP
A diferencia de usar jconsole localmente, debe anunciar una dirección IP diferente de la que probablemente verá desde el contenedor. Deberá reemplazar ${DOCKER_HOST_IP}
con la IP que se puede resolver desde el exterior (nombre DNS) de su host Docker.
JMX Remote y puertos RMI
Parece que JMX también requiere acceso a una interfaz de administración remota ( jstat ) que usa un puerto diferente para transferir algunos datos al arbitrar la conexión. No vi ningún lugar inmediatamente obvio en jconsole
para establecer este valor. En el artículo vinculado, el proceso fue:
- Pruebe y conéctese desde
jconsole
con el registro habilitado - Fallar
- Averiguar qué puerto
jconsole
intentó usar - Use
firewall
reglas deiptables
/firewall
según sea necesario para permitir que ese puerto se conecte
Mientras eso funciona, ciertamente no es una solución automatizable. Opté por una actualización de jconsole a VisualVM ya que permite especificar explícitamente el puerto en el que se ejecuta jstatd
. En VisualVM, agregue un nuevo host remoto y actualícelo con valores que se correlacionen con los especificados anteriormente:
A continuación, haga clic con el botón derecho en la nueva Conexión de host remota y Add JMX Connection...
No olvide marcar la casilla de verificación Do not require SSL connection
. Espero que eso te permita conectarte.
Ejecute su aplicación java con los siguientes parámetros de línea de comando:
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Es importante usar el parámetro -Dcom.sun.management.jmxremote.ssl = false si no desea configurar certificados digitales en el host jmx.
Si inició su aplicación en una máquina con una dirección IP 192.168.0.1 , abra jconsole , ingrese 192.168.0.1:8855 en el campo Proceso remoto y haga clic en Conectar .
En Linux, utilicé los siguientes parámetros:
-Djavax.management.builder.initial=
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
y también edité /etc/hosts
para que el nombre de host se resuelva en la dirección de host (192.168.0.x) en lugar de la dirección de bucle invertido (127.0.0.1)
Estoy usando WAS ND 7.0
Mi JVM necesita todos los siguientes argumentos para ser monitoreados en JConsole
-Djavax.management.builder.initial=
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
La documentación relevante se puede encontrar aquí:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
Comience su programa con los siguientes parámetros:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Por ejemplo, así:
java -Dcom.sun.management.jmxremote /
-Dcom.sun.management.jmxremote.port=9010 /
-Dcom.sun.management.jmxremote.local.only=false /
-Dcom.sun.management.jmxremote.authenticate=false /
-Dcom.sun.management.jmxremote.ssl=false /
-jar Notepad.jar
-Dcom.sun.management.jmxremote.local.only=false
no es necesariamente obligatorio, pero sin él, no funciona en Ubuntu. El error sería algo como esto:
01 Oct 2008 2:16:22 PM sun.rmi.transport. customer .TCPTransport$AcceptLoop executeAcceptLoop
WARNING: RMI TCP Accept-0: accept loop for ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=37278] throws
java.io.IOException: The server sockets created using the LocalRMIServerSocketFactory only accept connections from clients running on the host where the RMI remote objects have been exported.
at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:89)
at sun.rmi.transport. customer .TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
at sun.rmi.transport. customer .TCPTransport$AcceptLoop.run(TCPTransport.java:359)
at java.lang.Thread.run(Thread.java:636)
ver http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6754672
También tenga cuidado con -Dcom.sun.management.jmxremote.authenticate=false
que hace que el acceso esté disponible para cualquier persona, pero si solo lo usa para rastrear la JVM en su máquina local, no importa.
Actualización :
En algunos casos, no pude acceder al servidor. Esto se corrigió si establecí este parámetro también: -Djava.rmi.server.hostname=127.0.0.1
Tenga en cuenta que Java 6 en la última versión permite que jconsole se una a un proceso en ejecución incluso después de que se haya iniciado sin conjuros JMX.
Si está disponible para usted, también considere jvisualvm, ya que proporciona una gran cantidad de información sobre los procesos en ejecución, incluido un generador de perfiles.
Tuve este problema exacto y creé un proyecto de GitHub para probar y encontrar la configuración correcta .
Contiene un Dockerfile
funciona con scripts de apoyo, y un docker-compose.yml
simple para pruebas rápidas.