Camino de migas Camino de migas
Blogs (Tecnología) Blogs (Tecnología)
Realizando profiling de aplicaciones Java en JBoss

Durante el desarrollo de aplicaciones, tarde o temprano se suele plantear la cuestión del rendimiento de dicha aplicación. Existen múltiples métricas que pueden ser tenidas en cuenta como unidad de medida de rendimiento de una aplicación, y en función de las objetivos del desarrollo es necesario conseguir unos resultados u otros, por ejemplo:

  • el número de peticiones que es capaz de responder en un periodo de tiempo
  • el tiempo mínimo necesario para responder a una petición
  • el tiempo máximo para responder una petición
  • valores medios de un grupo de respuestas
  • ...

Para medir el rendimiento de una aplicación, inclyendo el número de peticiones que se responden y el tiempo necesario para responder las peticiones se suele utilizar herramientas que realizan tests de rendimiento o stress, como Apache Jmeter que permiten definir un conjunto de pruebas a realizar, y muestran estadísticas de los resultados.

Una vez que se ha medido el rendimiento de la aplicación, cuando se plantea la necesidad de la mejora del rendimiento de una aplicación, es posible seguir tres vías complementarias:

  • Optimización o ampliación del hardware o software contenedor.
  • Crecimiento horizontal de la arquitectura de aplicación. Diseñando una arquitectura que nos permita incluir nuevos servidores para aumentar el número de peticiones que el sistema es capaz de servir.
  • Y finalmente recurrir a la optimización del propio código fuente de la aplicación. En estos casos suele ser necesario recurrir o bien a procedimientos de inspección de código fuente, complementados con otros procedimientos de medición de rendimiento durante el funcionamiento de la aplicación denominados "profiling" que permiten determinar que optimizaciones serán las que aporten mayor rendimiento.

Mientras que la ampliación de hardware no tiene ningún misterio, y sobre arquitecturas de crecimiento horizontal ya hemos hablado en otros artículos, en este caso el artículo estará centrado en técnicas para la optimización de código.

El "profiling" es un técnica que permite inspeccionar el funcionamiento interno de una aplicación durante su tiempo de ejecución, lo que permite discernir el número de veces que están siendo usados cada uno de los componentes de la aplicación, y el tiempo que consume cada uno de esos componentes. El "profiling" puede ser realizado manualmente, incluyendo trazas en los componentes sobre los que se desean realizar mediciones, o se pueden utilizar herramientas preparadas para cada uno de los diferentes lenguajes de programación, llamadas profilers, que permiten o bien en tiempo de compilación incluyendo sobrecargas en el código, o bien en tiempo de ejecución interceptar las llamadas a cada uno de los componentes, que permite extraer durante la ejecución de la aplicación información sobre el número de veces que son ejecutadas y el tiempo consumido en cada ejecución.

Profiling en Jboss

Como prueba de concepto va a ser utilizado un servidor de aplicaciones Jboss, y una serie de aplicaciones desarrolladas en Java deplegadas en dicho servidor de aplicaciones. En el mercado actual existen múltiples "profilers", algunos de los cuales son software libre y otros software propietario. Por suerte la comunidad Jboss tiene su propio "profiler" llamado jboss-profiler, aplicación que debería ser suficiente para realizar una prueba de concepto de profiling.

Instalación de jboss-profiler

1. En primer lugar se descarga el profiler, para ello se accede a http://labs.jboss.com/jbossprofiler/ y se descarga la última versión disponible, en este caso de prueba fue la versión "jboss-profiler-2.0.0.Beta5.zip". Y se descomprime en un directorio:

# cd /opt
# unzip ~/jboss-profiler-2.0.0.Beta5.zip

2. Es necesario copiar ciertos ficheros al directorio de arranque de jboss "$JBOSS_HOME/bin", que se incluyen a continuación:

# cd jboss-profiler-2.0.0.Beta5
# cp jboss-profiler.jar $JBOSS_HOME/bin
# cp jboss-profiler-plugins.jar $JBOSS_HOME/bin
# cp jboss-profiler.properties $JBOSS_HOME/bin
# cp javassist.jar $JBOSS_HOME/bin

3. Se modifica el fichero "$JBOSS_HOME/bin/run.conf" para incluir nuevas opciones en "JAVA_OPTS":

  JAVA_OPTS="..... -javaagent:jboss-profiler.jar -Djboss- profiler.properties=jboss-profiler.properties"

4. Se modifica el fichero de configuración del jboss profiler, "$JBOSS_HOME/bin/jboss-profiler.properties", incluyendo que clases se quieren monitorizar y cuales se quieren excluir de la monitorización:

includes=com.andago.*|public,hero.*|public,org.postgres.*|public,fedora.*|public
excludes=org.jboss.*,com.andago.opencities.model.*|public

Nota: En este caso se comprueban las clases desarrolladas por Ándago, las del motor de workflow Bonita, las del gestor documental Fedora, y las de acceso a la base de datos Postgresql. Se han excluidos parte de las desarrolladas por Ándago en la rama "com.andago.opencities.model", porque utilizan la clase "cglib" que parecen entrar en conflicto con el sistema de profiling.

5. Es necesario desplegar el profiler en el servidor de aplicaciones, realizando lo siguiente:

# cp jboss-profiler.sar $JBOSS_HOME/server/default/deploy/

Una vez realizados los cambios ya es posible re-arrancar el servidor de aplicaciones, viendo que el servicio de profiling ha arrancado en los logs de arranque:

2009-09-09 13:06:59,563 INFO  [org.jboss.profiler.as.Profiler] JBoss Profiler: ProfilerMBean started
2009-09-09 13:06:59,563 INFO  [org.jboss.profiler.as.Communicator] JBoss Profiler: Communicator for JBoss Profiler 2.0.0.Beta5
2009-09-09 13:06:59,581 INFO  [org.jboss.profiler.as.Communicator] JBoss Profiler: Socket=0.0.0.0:5400
2009-09-09 13:06:59,631 INFO  [org.jboss.remoting.transport.coyote.CoyoteInvoker] Using org.apache.coyote.http11.Http11AprProtocol for http (coyote) invoker protocol handler.
2009-09-09 13:06:59,735 INFO  [org.apache.coyote.http11.Http11AprProtocol] Inicializando Coyote HTTP/1.1 en puerto http-0.0.0.0-5402
2009-09-09 13:06:59,781 INFO  [org.apache.coyote.http11.Http11AprProtocol] Arrancando Coyote HTTP/1.1 en puerto http-0.0.0.0-5402
2009-09-09 13:06:59,781 INFO  [org.jboss.profiler.as.Communicator] JBoss Profiler: Http=0.0.0.0:5402

Ejemplo de uso de jboss-profiler

Una vez en funcionamiento, es realmente sencillo realizar profiling del código. La aplicación de profiling incluye un cliente desde el que se puede realizar diferentes operaciones como pueden ser, arrancar el servicio de profiling, activarlo, salvar la información almacenada en el profiling, realizar un report, incluir nuevas clases a monitorizar y otras. Existe un manual incluido con la herramienta que explica todas las opciones "JBossProfiler2-UsersGuide.pdf".

Generando un snapshot y un report

La herramienta utiliza un sistema de "snapshots", que permiten descargar el contenido del profiling (que es almacenado en memoria o ficheros), permitiendo delimitar periodos de tiempo sobre los que se realiza el profiling. Por ello se recomienda seguir los siguientes pasos:

1. Se genera un snapshot para aislar las operaciones realizadas sobre la aplicación con anterioridad:

# cd jboss-profiler-2.0.0.Beta5
# java -Xmx512m -Djboss-profiler-client.properties=jboss-profiler-client.properties -jar jboss-profiler-client.jar snapshot

2. Se realizan las operaciones sobre las que se quiere realizar profiling. Se recomienda utilizar un sistema de pruebas automático, ya sea Apache Jmeter, o un script de seleniumhq.org/projects/ide/.

3. Se genera un snapshot+report final con los resultados de las pruebas.

# java -Xmx512m -Djboss-profiler-client.properties=jboss-profiler-client.properties -jar jboss-profiler-client.jar snapshot reportdirFinal

Con ello se genera un directorio llamado "reportdirFinal" en cuyo interior se incluye el report en varios ficheros "html", enlazados con un fichero "index.html", de modo que simplemente abriendo en un navegador el fichero "index.html" pueden verse los diferentes datos recogidos por la herramienta, incluyendo los threads, los métodos más usados, el número de veces utilizados, las clases cargadas:

JBoss Profiler 2.0.0.Beta5
Reports

    * Overview
    * Hotspots
    * Packages
    * Classes
    * Methods
    * Wait time

Cada una de la secciones permite acceder a diferente mediciones de datos, en la sección overview se puede ver (entre muchas otras cosas), los métodos que mayor tiempo consumen de ejecución, y el número de veces que se han llamado:

Most time
Count     Ms     Avg     %     Method
34     5440,92     160,03     33,00     com.andago.opencities.services.database.DatabaseServiceImpl#loadObjectById(Class, java.io.Serializable, boolean)
26     3253,73     125,14     19,73     com.andago.opencities.services.database.DatabaseServiceImpl#loadObjectListByFilter(Class, com.andago.opencities.managers.database.common.Filter, boolean)
3     623,35     207,78     3,78     com.andago.opencities.services.repository.client.fedora.apiM.ManagementSoapBindingStub#addDatastream(String, String, String[], String, boolean, String, String, String, String, String, String, String, String)


  • Comentarios
URL de Trackback: