Blog de Antonio Manuel Muñiz

Desarrollo, Ingeniería y Calidad del Software

Monitorización remota en Java: JConsole

Cuando ejecutamos pruebas de carga sobre una aplicación web en un entorno de producción nos enfrentamos a una serie de restricciones:

  • No podemos ejecutar ninguna herramienta en el entorno de producción. Debemos limitarnos a tocar parte de la configuración.
  • No tenemos interfaz gráfica
  • Las condiciones del entorno son “las que son”, no hay posibildad de cambio.

Para la ejecución de las pruebas no hay demasiados problemas, accedemos a modo de cliente, con herramientas como Tsung (comentada aquí hace poco tiempo) o The Grinder (con la que estoy teniendo una estrecha relación ultimamente, y escribiré algo pronto).

Los problemas vienen a la hora de tomar datos de rendimiento de la JVM mientras ejecutamos el load-test, que dadas las condiciones anteriores debemos hacerlo de forma remota. Hay varias herramientas que nos pueden ayudar, como son VisualVM o JConsole (ambas distribuidas con JDK 6). Yo me he quedado con JConsole por una sola razón: en modo remoto me proporciona más información sobre la JVM que VisualVM (para monitorizar en local, no hay duda, VisualVM es la elección).

Para configurar el acceso remoto de JConsole se debe lanzar la máquina virtual a monitorizar con las opciones:

-Djava.rmi.server.hostname=192.168.0.12
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9005
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

Comprobamos desde la máquina cliente (la que usaremos para lanzar JConsole) que el puerto está abierto en la máquina objetivo (en el ejemplo 192.168.0.12):

Antonio$> nmap 192.168.0.12 -p 9005
Starting Nmap 4.53 ( http://insecure.org ) at 2009-06-14 21:26 CEST
Interesting ports on 192.168.0.12:
PORT     STATE SERVICE
9005/tcp open  unknown

NMap done: 1 IP address (1 host up) scanned in 0.144 seconds

Sólo queda iniciar JConsole:

Antonio$> jconsole 192.168.0.12:9005

JConsole monitoriza memoria, CPU, Threads y clases instanciadas, además muestra un dashboard muy útil:

JConsole Dashboard

JConsole Dashboard

JConsole Memory

JConsole Memory

JConsole Classes

JConsole Classes

JConsole Summary

JConsole Summary

19 Respuestas a “Monitorización remota en Java: JConsole

  1. Manuel Jesús Recena Soto 14 junio 2009 en 11:53 pm

    Hola Antonio:

    Genial, veo que estás resolviendo la parte que el otro día nos faltaba. Conocer qué le pasa en el servidor mientras lanzamos las pruebas. Desde el cliente es fácil, ya “sufrimos” los resultados pero ahora puedes ver cuánto “sufre” el servidor.

    Dado que estas usando JMX, no olvides citarlo en tus conclusiones. Ese método, aunque es de los menos intrusivos, afecta al rendimiento.

    Buen trabajo.

  2. Abel Muiño 22 junio 2009 en 6:36 pm

    JConsole es un principio para observar qué pasa con el servidor (por cierto, está disponible no sólo en Java 6… como mínimo Java 5 tambien lo incluye).

    Lo siguiente es… porqué. Y eso ya es más dificil. Para los casos de consumo de memoria excesivo, me ha sorprendido lo bien que funciona Eclipse MAT (eso si, hay que acordarse de lanzar la aplicación con -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/para/volcados).

    Sobre la mención a herramientas para pruebas de carga, añadir JMeter. Es software maduro (y quizá poco interesante ;-) ), pero hace prácticamente de todo (muy similar a The Grinder).

    • Antonio Manuel Muñiz Martín 22 junio 2009 en 9:46 pm

      Hola Abel.

      Efectivamente, JDK 1.5 (que no JRE) también se incluye.

      El “porqué” es el objetivo final, normalmente lo obtenemos en base a un compendio de datos (análisis estático del código, la propia monitorización, y en casos más duros haciendo profiling, mirando en qué partes del código está más tiempo la línea de ejecución y analizando el código en cuestión). Eclipse MAT tiene buena pinta, habrá que probarlo.

      Por supuesto, JMeter es una buena opción. He apostado por “The Grinder” porque me ha parecido muy versátil (la posibilidad de poder distribuir el script de pruebas y los ficheros de configuración a los agentes al vuelo) y sobre todo por la potencia que proporciona el poder ejecutar un script Python (Jython en realidad) pudiendo hacer uso de cualquier funcionalidad que puedas conseguir con Python. Esto no hace que JMeter deje de ser interesante ;-) , y la madurez es un punto a su favor.

      Un saludo, y gracias por el comentario!

  3. Xavier 2 octubre 2009 en 2:06 pm

    Hola Antonio. Hace un par de días descubrí, como viene siendo habitual por accidente y por necesidad, lautilidad JConsole. He encontrado los parámetros de configuración que mencionas a cargar durante la ejecución de la JVM pero tengo una duda.

    En mi caso tengo un servidor con J2RE1.4.2_01 y un JRUN 4 instalado. La aplicación corre bajo el servidor JRUN y desconozco cómo hacer que la JVM cargue estos parámetros para poder conectarme de forma remota con la JConsole (que la tengo en otro servidor con el JDK).

    ¿Quizá tenga una versión de JRE antigua?
    ¿Hay que configurarlo en el servidor de JRUN?
    ¿Si instalo JDK en el servidor para poder tener la JConsole , podría tener algún problema?

    Gracias

    • Antonio Manuel Muñiz Martín 5 octubre 2009 en 12:00 am

      Hola Xavier.

      Si estás usando Java 1.4.X como máquina virtual para correr JRUN, lo tienes complicado. La monitorización a través de JMX en esta versión de la máquina virtual es muy limitada, no podrás ver información de consumo de memoria ni uso de threads.

      Si es posible deberías plantearte la migración a Java 1.5 (o mejor aún 1.6), no sólo por temas relacionados con la monitorización, también existen mejoras de rendimiento, bugs solucionados y mejoras funcionales incluidas en versiones posteriores a Java 1.4.

      En cuanto la configuración de JRUN, siento decirte que no tengo experiencia con este servidor, me muevo en un entorno más orientado al Open Source. En cualquier caso supongo que JRUN debe tener un script de arranque, comienza mirando por ahí, busca la variable JAVA_OPTS. Pero como te comento, con Java 1.4 no obtendrás los datos que esperas de JConsole.

      Un saludo.

  4. Pingback:La calidad del código fuente como punto de partida « Blog de Antonio Manuel Muñiz

  5. Marco Lago 28 junio 2012 en 5:05 pm

    Hola Antonio.
    Tengo en un servidor glassfish instalada varias intancias.
    ¿Tengo que hacer esta configuración para cada una de las instancias del servidor?
    ¿Solo con hacerlo en la instancia del servidor es suficiente para verlas todas?
    ¿Hay alguna opción para guardar en un archivo la información generada?

    De antemano te agradezco tu atención y muchas gracias por publicar esta información.

    • Antonio Manuel Muñiz Martín 28 junio 2012 en 7:48 pm

      Hola Marco,

      No entiendo el escenario, ¿tienes un sólo glassfish con varias aplicaciones? o ¿varios glassfish?
      Si sólo tienes un glassfish tendrás que monitorizar el proceso de la JVM sobre el que corre glassfish, si tienes varios tendrás que monitorizarlos por separado.

      Que yo sepa no hay forma de exportar los datos.

      Saludos!

      • Marco Lago 28 junio 2012 en 10:56 pm

        Gracias por responder.

        Tengo instalado un servidor glassfish. Hay una opción dentro del árbol de tareas comunes llamada: instancias independientes. Dentro creé tres instancias, cada una de ellas tiene un configuración para el JVM.

        Haciendo una analogía y tomando en cuenta lo que me dices, creo que hay que configurar cada instancia.

        Voy a revisar y cualquier cosa te comento.

        Nuevamente te agradezco la colaboración.

  6. Andrés 17 julio 2012 en 6:10 pm

    Hola,

    Mi consulta no es sobre el programa en sí, aunque lo encuentro de bastante utilidad también para lo que quiero hacer. Estoy intentando encontrar la forma de conocer qué cantidad de memoria RAM está siendo usada por Java Virtual Machine, para liberar memoria una vez llegado a un límite.

    Gracias de antemano por la ayuda.

    Saludos,
    Andrés

  7. Andrés 17 julio 2012 en 6:12 pm

    Se me olvidó decir que lo que me gustaría saber es cómo implementar esto en Java.

  8. Antonio Manuel Muñiz Martín 17 julio 2012 en 6:40 pm

    Hola Andrés,

    Para hacer lo que quieres tendrás que implementar algo a bajo nivel (http://docs.oracle.com/javase/1.5.0/docs/guide/jvmti/jvmti.html).

    Un saludo.

  9. adriana 23 octubre 2012 en 7:05 pm

    Hola Antonio
    Estoy tratand de monitorizar glassfish remotamente. En el archivo management,properties del servidor que deseo monitorizar coloque
    -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

    reseteo la pc

    desde la pc donde corro el jconsole ejecuto jconsole ip-pc-glassfish:9010 coloco user y pass y no se conecta

    Yo creo que no lo esta tomando pero no se como validarlo

  10. saco 15 enero 2013 en 11:05 am

    Hola Antonio, muy interesante tu trabajo.

    Estoy monitorizando pruebas con JConsole (antes lo hacía con VisualGC que lo veo much mas ligero), el caso es que me recomendaron JConsole para monitorizar el comportamiento del GC, para ver la vida de mis objetos en las distintas generaciones, pero no encuentro donde ver esto en JConsole (ni en VisualGC). Sabes si es posible ver esta información en esta u otra herramienta?, gracias por adelantado.

    • Antonio Manuel Muñiz Martín 16 enero 2013 en 10:58 am

      Hola,

      JConsole muestra información agregada de consumo de memoria. Hasta donde yo se no es posible monitorizar el tiempo de vida de un objeto concreto.
      Para esto tendrías que hacer profiling, usando herramientas como Eclipse Profiler (Eclipse TPTP), YourKit o InfraRed. Hay muchos más, elige el que más te guste.

      Saludos!

  11. wualfred arreola 7 junio 2013 en 8:59 am

    Hola Estimado Antonio, felicidades por el post, veo que adicional al puerto que se especifica, en tu caso el 9005 abre otro puerto que es automático y aleatorio por cada vez que reinicias, el detalle es que tengo un firewall donde debo abrir específicamente cada puerto.
    Sabes alguna forma de como predefinir ese otro puerto en algún script? de antemano muchas gracias, trabajo con tomcat 6.0.32 y java 7 sobre linux.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: