Archivo

Archivo del autor

Análisis de thread dumps en WebLogic: ThreadLogic

marzo 29, 2016 Deja un comentario

icono threadlogicSiguiendo con el tema de análisis de thread dumps, que se empezó en este otro post, vamos a centrarnos en la utilización de la aplicación ThreadLogic, que ha sido desarrollada por el equipo de arquitectos de Oracle FMW orientándola a dumps de servidores de aplicaciones. Se puede descargar aquí.

Al igual que Samurai y Thread Dump Analyzer (TDA), se trata de una aplicación libre que se arranca lanzando: java -jar <path fichero jar>

Comentar que para las pruebas se han utilizado las mismas aplicaciones que en el post anterior.

Diferencias con Thread Dump Analyzer (TDA)

El desarrollo de esta herramienta se ha realizado a partir de TDA:

  1. La información se muestra de una forma mucho más visual.
  2. La información está más categorizada:

threadlogic categorias dumps

  1. Está muy orientada al análisis de thread dumps de Oracle WebLogic Server:

threadlogic categorias dumps WLS

  1. Se puede filtrar por el estado del thread:

threadlogic filtro health

Stuck threads

Los stuck threads se marcan con este estado a nivel de servidor de aplicaciones cuando un thread está corriendo durante más de X segundos.

Leer más…

Análisis de thread dumps en WebLogic

Hace unos meses escribí este post donde os explicaba qué son los stuck threads y cómo detectarlos.

En el post de hoy os voy a presentar algunas herramientas que os pueden ser útiles para realizar el análisis de thread dumps, necesarios para la detección de stuck threads, deadlocks, etc.

Sin embargo, no hay que perder de vista el hecho de que como administradores únicamente podremos saber dónde está el problema, no solventarlo.

 

Ejecución de pruebas

Por si tenéis interés en realizar vuestras propias pruebas, aquí podéis encontrar una aplicación para provocar deadlocks, gentileza de nuestro compañero Àngel Ollé.

Una vez desplegada en una instancia WebLogic, se puede provocar un deadlock realizando peticiones a http://ip:puerto/DeadLockServlet/dl

Para generar stuck threads podéis utilizar la aplicación StuckThreadForFree realizando llamadas a http://ip:puerto/StuckThreadForFree sobre la instancia WebLogic.

Se definen cuántos threads levantar, cuántos segundos mantenerlos levantados y qué operación estarán ejecutando durante ese tiempo:

stuckthreadforfree prueba

¿Qué herramienta utilizar?

Hay muchas herramientas en el mercado pero las más comúnmente utilizadas, que además son libres, son:

  1. Samurai
  2. Thread Dump Analyzer (TDA)
  3. ThreadLogic

Todas consisten en un JAR, por lo que su ejecución es tan simple como lanzar ‘java -jar <path fichero jar>’. La diferencia reside en cómo se muestra la información en la interfaz.

Una vez se ha iniciado la aplicación, abrimos el fichero de texto donde tenemos el thread dump.

Comentar que las aplicaciones pueden interpretar ficheros con varios thread dumps.

 

1. Samurai

Descarga: http://yusuke.homeip.net/samurai/en/samurai.jar

Es una aplicación muy intuitiva donde se identifican con facilidad bloqueos:

Samurai threads bloqueados

Leer más…

Problemas de rendimiento en una JVM

agosto 20, 2015 1 comentario

java

Si te dedicas a la administración de sistemas Middleware, tarde o temprano acabas encontrando problemas de rendimiento sobre las aplicaciones. Hay muchos factores que pueden afectar al rendimiento, como puede ser una aplicación mal desarrollada, consultas en base de datos con tiempo de ejecución elevado, latencias de comunicaciones y un largo etcétera.

En el caso de WebLogic, las instancias no son otra cosa que un proceso Java y, como tal, una mala configuración también puede empeorar el rendimiento.

En este post nos vamos a centrar en la configuración de la memoria de procesos Java.

¿Qué información necesitamos?

Para poder analizar el comportamiento de la memoria de procesos Java es imprescindible recoger las trazas de Garbage Collector (GC). Esto se configura en el arranque del proceso Java mediante unas variables.

Estas trazas aportan datos sobre:

  • Tiempo de ejecución de GC.
  • Estado de la memoria (young, old y permanent) antes y después de las limpiezas.
  • Si se han ejecutado Full GC (FGC) y cuánto han estado ejecutándose: este dato es especialmente importante puesto que durante un FGC la instancia se queda congelada.

Un ejemplo de esta información sería (en esta traza de ejecución no se han realizado FGC):

2015-08-19T00:49:03.965+0200: 9,759: [GC pause (young), 0,0176360 secs]
   [Parallel Time: 15,7 ms, GC Workers: 2]
      [GC Worker Start (ms): Min: 9759,0, Avg: 9759,3, Max: 9759,6, Diff: 0,6]
      [Ext Root Scanning (ms): Min: 3,2, Avg: 3,5, Max: 3,7, Diff: 0,5, Sum: 7,0]
      [Update RS (ms): Min: 0,0, Avg: 0,0, Max: 0,0, Diff: 0,0, Sum: 0,0]
         [Processed Buffers: Min: 0, Avg: 6,5, Max: 13, Diff: 13, Sum: 13]
      [Scan RS (ms): Min: 0,0, Avg: 0,1, Max: 0,1, Diff: 0,1, Sum: 0,1]
      [Object Copy (ms): Min: 11,8, Avg: 11,8, Max: 11,8, Diff: 0,0, Sum: 23,6]
      [Termination (ms): Min: 0,0, Avg: 0,0, Max: 0,0, Diff: 0,0, Sum: 0,0]
      [GC Worker Other (ms): Min: 0,0, Avg: 0,0, Max: 0,0, Diff: 0,0, Sum: 0,1]
      [GC Worker Total (ms): Min: 15,1, Avg: 15,4, Max: 15,7, Diff: 0,6, Sum: 30,8]
      [GC Worker End (ms): Min: 9774,7, Avg: 9774,7, Max: 9774,7, Diff: 0,0]
   [Code Root Fixup: 0,1 ms]
   [Clear CT: 0,1 ms]
   [Other: 1,8 ms]
      [Choose CSet: 0,0 ms]
      [Ref Proc: 1,6 ms]
      [Ref Enq: 0,1 ms]
      [Free CSet: 0,1 ms]
   [Eden: 89,0M(89,0M)->0,0B(89,0M) Survivors: 13,0M->13,0M Heap: 102,2M(2048,0M)->15,0M(2048,0M)]
 [Times: user=0,03 sys=0,00, real=0,02 secs]

¿Cómo interpretamos esta información?

A pesar que las trazas de GC se pueden abrir con cualquier editor de texto, analizar estas trazas manualmente es muy tedioso y lento.

Hay varias herramientas que permiten ver esta información gráficamente y que, además, muestran estadísticas. La más comúnmente utilizada es GCViewer. Es un proyecto opensource que se mantiene vivo.

Antes de empezar

Explicar cómo ver si hay algún problema y cómo solucionarlo es un tema para el que se han escrito libros enteros, por lo que es imposible explicarlo en un post.

Aunque va a gustos, dejo algún libro que he utilizado como referencia (para mi opinión, de obligada lectura si te dedicas al sector):

  • Java Performance: The Definitive Guide“, de Scott Oaks
  • Java Performance“, de Charlie Hunt y Binu John (chapter 7: Tuning the JVM, Step by Step)

Antes de empezar, hay que tener muy en cuenta que:

  1. Realizar un buen análisis es una tarea que no se realiza en un momento. En la mayoría de los casos estamos hablando de una semana de trabajo exhaustivo.
  2. Una mala configuración puede empeorar el rendimiento. Puede llegar a ser peor el remedio que la enfermedad.

Resumiendo: ármate de paciencia y de buena documentación.

Ideas generales

  1.  ¿Cada vez que se ejecuta un FGC es realmente necesario? En versiones anteriores de JDK, cada 60 segundos se ejecutaba, de forma sistemática, un FGC. Este comportamiento no es el deseado, pero se puede evitar añadiendo unas variables en el arranque del proceso Java.
  2. Ampliar el tiempo entre ejecuciones de FGC puede sacar a la luz otros problemas. Los FGC ejecutados sin necesidad pueden estar ocultando leaks de memoria, que acabarían degradando aún más el rendimiento del proceso Java.
  3. Aumentar los espacios de memoria (sea cual sea) provoca un aumento en el tiempo de ejecución de GC y FGC. A veces, menos es más.
  4. La solución no tiene por qué venir únicamente del tuning de la VM. En algunos casos, pasa por el desarrollo de la aplicación que corre por encima (reducir los objetos en memoria y/o el tiempo de permanencia de estos objetos en memoria).
  5. Si se observa que el espacio de memoria young se llena con facilidad y estos objetos se van promocionando a la old, para al poco tiempo borrarse de la old, una solución podría ser aumentar el tamaño de la zona Young en detrimento de la old con el objetivo de disminuir estas promociones a la zona old, además de disminuir el tiempo y frecuencia de los FGC.
  6. Cada vez que se modifica un parámetro de configuración en el arranque, hay que volver a recolectar logs de GC para realizar una comparativa y ver si el cambio ha sido positivo.

Threads stuck en WebLogic

En este post vamos a explicar qué son y cómo analizar los threads stuck en WebLogic. Ante todo hay que tener en cuenta que el hecho que un thread sea considerado stuck (traducción literal: “atascado”) no implica, necesariamente, que existe alguna problemática de fondo.

¿Qué es un thread stuck?

Cuando un thread está levantado durante demasiado tiempo, ya sea haciendo una pausa (por ejemplo, por un sleep) como realizando trabajo activo (como calcular decimales del número pi), se marca como stuck. Este thread no ha sido capaz de completar su trabajo y, por lo tanto, no acepta nuevas peticiones. El problema viene cuando un proceso empieza a marcar todos sus threads como stuck.

¿Qué podemos hacer para detectarlos?

WebLogic detecta automáticamente los threads stuck pero se pueden tomar varias acciones ante esta situación:

  1. Overload Protection: Se puede configurar a nivel de instancia cómo reaccionar ante situaciones de sobrecarga. Se define cuánto tiempo esperar antes de marcar un thread como stuck, cuántos threads en stuck se pueden permitir y qué acción tomar entre pasar la instancia a modo ADMIN o pararla directamente. En cualquiera de los casos, se ha de tener en cuenta que la acción afecta a la instancia (en el caso que una instancia desplegase varias aplicaciones, todas se verían afectadas).
    overload protection
  2. También se puede configurar que el Work Manager asociado se pare, volviendo a estar activo en el caso que dejase de superarse el umbral de threads stuck.
    workmanager_workload
  3. Módulos de diagnóstico: WebLogic proporciona por defecto la funcionalidad de módulos de diagnóstico, configurable a través de la consola de administración o WLST. Esto consiste, básicamente, en monitorizar la métrica de StuckThreadCount de runtime del servidor y definir un umbral. En caso de superación, se pueden tomar varias acciones: enviar un correo, crear un mensaje JMS, lanzar una imagen de diagnóstico, enviar una notificación JMX o enviar un trap SNMP.
    Las imágenes de diagnóstico consisten en un fichero .zip con varios ficheros .img (que se pueden abrir en texto plano) que aportan información completa del estado de la instancia (es una captura del estado de la instancia).
    También se puede utilizar el explorador WLDF para abrir estos ficheros .zip, que organiza la información en forma de árbol.
  4. Acciones correctivas desde Cloud Control: En el supuesto que se tengan importadas las instancias en cloud Control, se pueden definir umbrales de advertencia y críticos y asociar una acción correctiva a dichos umbrales. Estas acciones pueden ir desde reiniciar la instancia a lanzar un script propio.cc_corrective_action

¿Qué análisis podemos hacer?

Para poder analizar los threads stuck, es importante disponer de la siguiente información:

  • Thread dump: es importante lanzar varios thread dumps en un intervalo de tiempo, para poder analizar la evolución en el uso de threads.
  • Consumo de los threads stuck: a partir de un thread dump se puede obtener el identificador del thread y, con este identificador, el consumo de cpu y memoria de estos threads mediante, por ejemplo, un comando ‘ps’.
  • Heap dump: en determinadas circunstancias puede ser interesante lanzar un heap dump (recordad que esto deja congelada la instancia).

Con toda esta información se ha de analizar:

  1. ¿Están consumiendo muchos recursos? En caso afirmativo sería interesante analizar los recursos de la máquina.
  2. ¿Están ejecutando lo mismo, usando las mismas clases o llamando al mismo servicio backend? Una actualización en el código de la aplicación puede provocar la aparición de estos threads, ya sea por un mal desarrollo o por factores que no se han tenido en cuenta (esperas demasiado largas, no configuración de timeouts, etc.).
    También puede ser que si la aplicación llama a otro servicio, sea ese el que esté provocando la aparición de estos threads.

En cualquier caso, descubrir la causa de estos threads no suele ser sencillo y suele ser necesario colaborar con los equipos de desarrollo para analizar la información recolectada.