Métodos para monitorizar remotamente Jboss EAP 6+/Wildfly 8+ con VisualVM

By | December 6, 2016

VisualVM (o JVisualVM si utilizamos la herramienta de la JDK) es una herramienta esencial tanto para realizar troubleshooting como para monitorizar los distintos componentes de nuestro servidor de aplicaciones.

Ofrece capacidades de monitorización de threads y generaciones de memoria, acceso/control de mbeans remotos y volcados de memoria/threads entre otros.

Monitor de heap, CPU, clases...

Monitor de heap, CPU, clases…

Visualización de threads

Visualización de threads

Monitorización avanzada de memoria con el plugin VisualGC

Monitorización avanzada de memoria con el plugin VisualGC

Para cumplir con su función la herramienta necesita asociarse (attach) a un determinado proceso Java. Teniendo en cuenta que en la mayor parte de las ocasiones el proceso Java estará siendo ejecutado en una máquina remota, podemos realizar la monitorización de tres formas:

  • Conectándonos a un demonio jstatd que se ejecutará en la máquina remota. Este demonio expone los procesos Java -actuando como proxy- de esa máquina para poder ser monitorizados externamente.
  • Conectándonos por JMX al servidor Jboss remoto. Requerirá configuración adicional en nuestro servidor de aplicaciones.
  • Exportando las X a nuestra máquina local y lanzando VisualVM/JVisualVM desde la máquina remota. La forma más sencilla.

Exponer procesos Java al exterior con jstatd

Ejecutar el demonio jstatd es una forma sencilla de acceder a todos los procesos Java que se encuentran en una máquina remota. Debemos tener en cuenta dos inconvenientes de este método:

  • Desde un punto de vista de la seguridad, utilizar jstatd expone todos nuestros procesos Java a conexiones externas sin necesidad de autenticación. Por lo tanto, si utilizamos jstatd debemos hacerlo de forma temporal o limitando los accesos a través de un firewall como iptables.
  • Podríamos considerar jstatd como un “proxy” entre nuestra máquina local y el proceso Java remoto que queremos monitorizar, pero nada más. Al no utilizar la API JMX no podremos beneficiarnos de las capacidades de esta como por ejemplo el acceso y operación sobre mbeans remotos.

Para configurar el acceso desde jstatd seguiremos estos pasos:

  1. Crear fichero jstatd.all.policy en el servidor remoto con el siguiente contenido. Cambiará según la versión de JDK que estés utilizando:
    grant codebase "file:/opt/java/jdk1.8.0_74/lib/tools.jar" {
            permission java.security.AllPermission;
    };
    

    En mi caso he creado el fichero en /opt/java/jstatd.all.policy

  2. Ejecutar jstatd en el servidor remoto especificando el puerto de escucha.
    /opt/java/jdk1.8.0_74/bin/jstatd -p 8888 -J-Djava.security.policy=/opt/java/jstatd.all.policy
    

    Si da problemas probar sin el prefijo -J (se supone que con a partir de la JDK 8 debería ser sin prefijo, aunque yo he tenido que añadirlo en algunas pruebas)

    /opt/java/jdk1.8.0_74/bin/jstatd -p 8888 -Djava.security.policy=/opt/java/jstatd.all.policy
    
  3. En nuestra máquina local, ejecutamos Visualvm/JVisualVM. Añadimos un host remoto (en mi caso 192.168.1.34) y después una conexión jstatd especificando el puerto de escucha remoto de jstatd:

Conexión JMX a servidor remoto

Si nuestro Jboss/Wildfly está en modo dominio, tendremos que añadir la línea remoting-connector use-management-endpoint=”false” en el subsistema JMX del perfil que estemos utilizando, por ejemplo el ha:

<profile name="ha">
...
    <subsystem xmlns="urn:jboss:domain:jmx:1.2">
         <expose-resolved-model/>
         <expose-expression-model/>
         <remoting-connector use-management-endpoint="false"/>
    </subsystem>
...
</profile>

Por defecto el punto de escucha JMX para una instancia de Jboss en modo dominio es el 4447. Si tenemos varias instancias entonces deberíamos sumar a este puerto el offset correspondiente.

Para modo standalone, no es necesario realizar ningún cambio en el servidor de aplicaciones.

También tenemos un requisito que cumplir en la máquina (local) en la que vamos a lanzar la herramienta VisualVM. Si en nuestro servidor remoto estamos utilizando una versión antigua Jboss EAP 6.0.1 tendremos que copiar la librería jboss-modules.jar y los módulos de Jboss al directorio platform/lib/ de nuestro paquete VisualVM descargado en nuestra máquina local. En cualquier caso, esa versión de Jboss está prácticamente desfasada y es conveniente actualizar mínimo a Jboss 6.4 en estos momentos.

Para versiones Jboss EAP 6.1.0 y superiores bastará con copiar jboss-cli-client.jar localizado en $JBOSS_HOME/bin/client/jboss-cli-client.jar al directorio platform/lib/ de nuestro paquete VisualVM descomprimido:

[bob@jotadebian visualvm_139]$ pwd
/home/bob/Downloads/visualvm_139
[bob@jotadebian visualvm_139]$ ls -l platform/lib/
total 8364
-rw-r--r-- 1 bob bob  412745 Oct  2  2016 boot.jar
-rw-r--r-- 1 bob bob 4893249 Sep  1 21:12 jboss-cli-client.jar
-rwxr-xr-x 1 bob bob   14860 Oct  2  2016 nbexec
-rwxr-xr-x 1 bob bob 1480851 Oct  2  2016 nbexec64.dll
-rwxr-xr-x 1 bob bob  210432 Oct  2  2016 nbexec64.exe
-rwxr-xr-x 1 bob bob  429570 Oct  2  2016 nbexec.dll
-rwxr-xr-x 1 bob bob  152064 Oct  2  2016 nbexec.exe
-rw-r--r-- 1 bob bob   36489 Oct  2  2016 org-openide-modules.jar
-rw-r--r-- 1 bob bob  629692 Oct  2  2016 org-openide-util.jar
-rw-r--r-- 1 bob bob  289699 Oct  2  2016 org-openide-util-lookup.jar

También tenemos la opción de añadir el .jar necesario al classpath de VisualVM:

./bin/visualvm -cp:a /opt/middleware/jboss-eap-6.4/bin/client/jboss-cli-client.jar

Teniendo estas dependencias cubiertas, posteriormente lanzaremos la utilidad y crearemos una conexión JMX (en la imagen anterior de conexión jstatd podéis ver dónde realizarlo) en utilizando la siguiente cadena de conexión:

service:jmx:remoting-jmx://192.168.1.34:9999

Siendo 192.168.1.34 la IP remota y 9999 el mismo puerto de escucha de la CLI. Para autenticarnos, utilizaremos un usuario administrativo que tendremos que haber creado anteriormente con el script add-user de Jboss.

Exportando las X a nuestra máquina local

Este método considero que es el más sencillo, aunque necesitaremos un servidor X en nuestra máquina local. Si utilizamos Windows Xming puede ser una solución. Se pueden seguir las instrucciones que ya comenté en un artículo anterior.

Una vez tengamos las X exportadas a nuestra máquina local, en el servidor remoto ejecutaremos VisualVM o JVisualVM. El resultado es que al tener exportadas las X en local, podremos utilizar con total funcionalidad (acceso a capacidades JMX y Visual GC) la herramienta que en realidad se está ejecutando en el servidor remoto.