¿Cómo activar JMX en una JVM para acceder con jconsole?
¿Cómo activar JMX en una JVM para acceder con jconsole?
Respuestas:
La documentación relevante se puede encontrar aquí:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
Inicie su programa con los siguientes parámetros:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.rmi.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 lo-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 llegar al servidor. Esto se solucionó si configuro este parámetro también:-Djava.rmi.server.hostname=127.0.0.1
com.sun.management.jmxremote
tenga el valor predeterminado como true
. (¡Gracias Sun!) Para ser súper claro, especialmente para aquellos menos familiarizados con los nobs de JMX, uso: com.sun.management.jmxremote=true
Ref: docs.oracle.com/javase/8/docs/technotes/guides/management/…
Dcom.sun.management.jmxremote.rmi.port=9011
y abrir en el firewall, aún no puedo conectarme con el firewall activo. ¿Alguna idea? ¿Me he perdido algo?
Ejecutar en un contenedor Docker introdujo una gran cantidad de problemas adicionales para conectarse, por lo que espero que esto ayude 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 IP diferente de la que probablemente verá desde el contenedor. Deberá reemplazarlo ${DOCKER_HOST_IP}
con la IP (nombre DNS) que se puede resolver externamente de su host Docker.
Puertos remotos JMX y 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 jconsole
para establecer este valor. En el artículo vinculado, el proceso fue:
jconsole
con el registro habilitadojconsole
intentó usariptables
/ firewall
reglas según sea necesario para permitir que ese puerto se conecteSi bien eso funciona, ciertamente no es una solución automatizable. Opté por una actualización de jconsole a VisualVM ya que le permite especificar explícitamente el puerto en el que se jstatd
está ejecutando. En VisualVM, agregue un nuevo host remoto y actualícelo con valores correlacionados con los especificados anteriormente:
Luego haga clic con el botón derecho en la nueva Conexión de host remoto y Add JMX Connection...
No olvide marcar la casilla de verificación para Do not require SSL connection
. Con suerte, eso debería permitirle conectarse.
-Djava.rmi.server.hostname=localhost
-Dcom.sun.management.jmxremote.rmi.port=[...]
es también la clave en caso de tunelizar JMX / RMI a través de SSH. Sin ellos, se accede a los objetos remotos utilizando la IP pública / principal / ... del servidor utilizando algún puerto aleatorio, que no se puede reenviar fácilmente.
-Djava.rmi.server.hostname=0.0.0.0
DOCKER_HOST_IP
en cualquier lugar - que acabo de utilizar localhost
y ha remitido los puertos cuando se ejecuta la imagen ventana acoplable: -p 9998:9998, -p 9999:9999
etc
Tenga en cuenta que Java 6 en la última encarnación permite que jconsole se adjunte a un proceso en ejecución incluso después de que se haya iniciado sin encantamientos JMX.
Si eso está disponible para usted, considere también jvisualvm, ya que proporciona una gran cantidad de información sobre los procesos en ejecución, incluido un generador de perfiles.
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
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)
Ejecute su aplicación Java con los siguientes parámetros de línea de comandos:
-Dcom.sun.management.jmxremote.port=8855
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Es importante utilizar 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 la dirección IP 192.168.0.1 , abra jconsole , coloque 192.168.0.1:8855 en el campo Proceso remoto y haga clic en Conectar .
-Dcom.sun.management.jmxremote.ssl=false
? ¿Debería jconsole
mostrar un error, o simplemente no se conectaría en silencio?
junto con los siguientes parámetros de línea de comando,
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
A veces, en los servidores de Linux, la conexión imx no se realiza correctamente. Esto se debe a que, en el host Linux de la nube, en / etc / hosts para que el nombre del host se resuelva en la dirección del host.
la mejor manera de solucionarlo es hacer ping al servidor Linux en particular desde otra máquina en la red y usar esa dirección IP de host en el
-Djava.rmi.server.hostname=IP address that obtained when you ping that linux server.
Pero nunca confíe en la ipaddress que obtiene del servidor linux usando ifconfig.me. la ip que obtienes allí está enmascarada y está presente en el archivo host.
Primero debe verificar si su proceso de Java ya se está ejecutando con parámetros JMX. Hacer esto:
ps -ef | grep java
Verifique el proceso de Java que necesita monitorear. Si puede ver el parámetro jmx rmi Djmx.rmi.registry.port = xxxx , use el puerto mencionado aquí en su visualvm de java para conectarlo de forma remota con una conexión jmx.
Si no se ejecuta a través del puerto jmx rmi, entonces debe ejecutar su proceso java con los parámetros mencionados a continuación:
-Djmx.rmi.registry.port=1234 -Djmx.rmi.port=1235 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
Nota: los números de puerto se basan en su elección.
Ahora puede usar este puerto para la conexión jmx. Aquí está el puerto 1234
.
sudo lsof -i:1234
no muestra nada para mí
Paso 1: Ejecute la aplicación usando los siguientes parámetros.
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
Los argumentos anteriores vinculan la aplicación al puerto 9999.
Paso 2: Inicie jconsole ejecutando el comando jconsole en el símbolo del sistema o terminal.
Seleccione 'Proceso remoto:' e ingrese la url como {IP_Address}: 9999 y haga clic en el botón Conectar para conectarse a la aplicación remota.
Puede consultar este enlace para completar la solicitud.
Tuve este problema exacto y creé un proyecto de GitHub para probar y descubrir la configuración correcta .
Contiene un trabajo Dockerfile
con scripts de soporte y un simple docker-compose.yml
para pruebas rápidas.