En sí Java es un programa muy extenso enfocado en la complejidad de un sistema operativo. Usualmente mientras esta en estado estable, como cualquier otro programa ocasionalmente sufre problemas por ejemplo cuando el sistema se bloquea, sufre congelamientos, etcétera. Cuando el proceso de una aplicación Java se congela, puede ser difícil detectarlo y recuperarse del mismo. Debido a que el proceso Java aún existe en la memoria, muchas aplicaciones de monitoreo externas pensarán que dicho proceso esta trabajando cuando en realidad ha dejado de responder.

Cuando la máquina JVM se congela, por lo general es observado por usuarios u otros sistemas que dejan de interactuar con la aplicación. Una vez que el problema es identificado, a menudo a través de usuarios que lo ha enviado alguna queja un administrador de sistemas debe conectarse al servidor, eliminar la JVM congelada y reiniciar la aplicación. Todo esto puede tomar un par de horas si el administrador encargado se encuentra fuera de la oficina.

Solución

La Solución a este problema es tener una aplicación de monitoreo, con un conocimiento profundo de cómo funciona Java. Una aplicación en la que se pueda confiar para monitorear su aplicación Java las 24 horas del día los 365 días del año. De la misma manera hacerse cargo automáticamente de cualquier problema que se presente.

El Java Service Wrapper tiene varias funciones de monitoreo. Una de ellas es la capacidad para detectar cuando una JVM se ha congelado. El Wrapper constantemente monitorea una JVM y contiene una logica avanzada para decidir si una JVM esta o no congelada. Cuando se detecta que una JVM se ha congelado, el Wrapper automáticamente la reinicia para tener el sistema de trabajando en un tiempo mínimo de inactividad. El Wrapper puede entonces enviar una notificación a través de un email al administrador de sistemas en caso de que desee confirmar que el servicio se ha recuperado y que está trabajando normalmente.

El Java Service Wrapper periódicamente rastrea (ping) al proceso Java (por defecto cada 5 segundos) y espera por una respuesta. Si la respuesta no es recibida durante un periódo configurado de tiempo (por defecto 30 segundos), entonces el Wrapper determinará que esta congelado. El Wrapper también toma en consideración aspectos como carga total del sistema para asegurarse que falsos positivos se mantengan a un mínimo.

Cuando un congelamiento es detectado, el Wrapper registrará algo como lo que a continuación se presenta en el archivo de registro de valores:

Ejemplo de Registro de Valores de un Congelamiento y Reinicio:
jvm 1    | ...
wrapper  | JVM parece estar colgada: Tiempo de Espera:  Esperando una señal de la JVM.
wrapper  | JVM did not exit on request, terminated
wrapper  | Iniciando JVM...
jvm 2    | WrapperManager: Initializing...
jvm 2    | ...

El Wrapper ayuda a detectar problemas críticos incluyendo:

Descripción Técnica

La detección de congelamientos esta configurada por defecto. Intentará rastrear la JVM cada 5 segundos y que el tiempo de espera termine después de 30 segundos sin recibir una respuesta. Estos dos intervalos son configurables. Al configurar la propiedad wrapper.debug=TRUE podrá ver dichos rastreadores en el archivo de registro de valores. En este ejemplo el formato de registro ha sido configurado para que también incluya fecha y hora.

Ejemplo de Registro de Rastreadores (Pings):
INFO   | jvm 1    | 2012/05/09 18:28:11 | ...
DEBUG  | wrapperp | 2012/05/09 18:28:13 | Enviar un paquete PING : ping
INFO   | jvm 1    | 2012/05/09 18:28:13 | WrapperManager Debug: Received a packet PING : ping
INFO   | jvm 1    | 2012/05/09 18:28:13 | WrapperManager Debug: Send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 18:28:13 | Leer un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 18:28:18 | Enviar un paquete PING : ping
INFO   | jvm 1    | 2012/05/09 18:28:18 | WrapperManager Debug: Received a packet PING : ping
INFO   | jvm 1    | 2012/05/09 18:28:18 | WrapperManager Debug: Enviar a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 18:28:18 | Leer un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 18:28:21 |...

Detección de Congelamientos

Compatibilidad :1.0.0
Ediciones :Edición ProfesionaEdición EstándarEdición de la Comunidad
Plataformas :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/OSIBM z/Linux

El proceso de rastreo de la JVM es una característica muy ligera. Se recomienda monitorear la JVM con los intervalos configurados por defecto de 5 segundos. Dependiendo de su aplicación o en los casos cuando el sistema se encuentra bajo cargas externas muy altas, tal vez sea necesario extender el tiempo de espera del rastreador. Tenga en mente que al hacerlo, incrementará el tiempo que le tomará al Wrapper en decidir si la JVM esta congelada.

Note como en este ejemplo se muestra que cuando una JVM se congela, dejará de responder a todos los rastreadores y el Wrapper iniciará un reinicio:

Ejemplo de Registro de Valores: Congelamiento y Reinicio.
DEBUG  | wrapperp | 2012/05/09 19:20:22 | Enviar un paquete PING : ping
INFO   | jvm 1    | 2012/05/09 19:20:22 | WrapperManager Debug: Received a packet PING : ping
INFO   | jvm 1    | 2012/05/09 19:20:22 | WrapperManager Debug: Send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:22 | Leer un paqute    PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:27 | Enviar un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:31 | Enviar un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:36 | Enviar un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:27 | Enviar un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:31 | Enviar un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:36 | Enviar un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:27 | Enviar un paquete PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:31 | Enviar un paquete PING : ping
ERROR  | wrapper  | 2012/05/09 19:20:59 | JVM parece estar colgada: Tiempo de Espera:  Esperando una señal de la JVM.
ERROR  | wrapper  | 2012/05/09 19:21:00 | JVM did not exit on request, terminated

Probando

Deseamos tenga dificultades para experimentar o tener que reproducir que la JVM se congele en su aplicación Java. Para hacer más fácil este tipo de pruebas, la aplicación de ejemplo TestWrapper viene incluida con el Wrapper. Esta aplicación puede ser usada para probar ésta y otras propiedades más.

Por favor ejecutar la aplicación TestWrapper desde una consola desde donde esta descargado el Java Service Wrapper. En Windows ejecute bin\TestWrapper.bat y en plataformas UNIX bin\testwrapper console.

Cuando la aplicación de ejemplo TestWrapper inicia, debería ver una pantalla GUI con una lista de botones del lado izquierdo. Al presionar Simular que la JVM se cuelgue causará que la JVM parezca congelada ante el Wrapper.

Ejemplo de Registro de Valores:Congelamiento y Reinicio.
jvm 1    | TestWrapper: Mostrando diálogo...
jvm 1    | WrapperManager: WARNING: Making JVM appear to be hung...
wrapper  | Error en el Apagado: Tiempo de espera: Esperando por una señal de la JVM.
wrapper  | JVM did not exit on request, terminated
wrapper  | Launching a JVM...
jvm 2    | WrapperManager: Initializing...
jvm 2    | TestWrapper: Inicializando...

Si desea probar esta propiedad en su aplicación Java, es posible hacerlo al llamar WrapperManager.appearHung() para entrar en este modo de prueba.

Respondiendo a Eventos

Compatibilidad :3.3.0
Ediciones :Edición ProfesionaEdición Estándar (No Soportado)Edición de la Comunidad (No Soportado)
Plataformas :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/OSIBM z/Linux

En ocasiones cuando una aplicación se congela o bloquea, un reinicio no siempre es suficiente. Si archivos temporales no fueron limpiados correctamente y/o la base de datos se encuentra en un estado inestable, la nueva instancia de la aplicación puede fallar rápidamente con errores. Lo ideal es que la aplicación sea diseñada para ser lo suficientemente robusta para gestionar estos errores, pero no siempre es posible. En estos casos se necesita una manera para hacer una limpieza antes de iniciar una JVM nueva.

El Wrapper apoya a través del uso de Comandos de Eventos. Es posible ordenar al Wrapper que ejecute un comando externo o archivo de órdenes en diversos momentos.

Si observa en la depuración de registro de valores de la salida de datos verá entradas de eventos como estas Enqueue Event 'NNN'. Esto significa el momento en el que fueron ejecutados los eventos del Wrapper. En el caso de reinicios después de detectar una JVM congelada, lo que queremos es iniciar una limpieza de los archivos de órdenes antes deque una nueva instancia JVM sea iniciada. El evento jvm_restart será usado.

Crear un archivo de órdenes simple como se indica y colocarlo en el mismo directorio del Wrapper binario. Este ejemplo simplemente simula una tarea de limpieza de 10 segundos. Un archivo real resultaría más interesante.

Ejemplo de Secuencia de comandos: "cleanupTest.bat"
@echo off
echo Limpiando por 10 segundos...
rem usar ping para generar un retraso de 10 segundos.
PING 1.1.1.1 -n 1 -w 10000 >NUL
echo Proceso de Limpieza completo.

El siguiente paso es agregar las siguientes propiedades al archivo wrapper.conf.

Configuración del archivo "wrapper.conf"
wrapper.event.jvm_restart.command.argv.1=cleanupTest.bat
wrapper.event.jvm_restart.command.block=TRUE
wrapper.event.jvm_restart.command.loglevel=INFO

Ahora cuando se detecte un congelamiento, el Wrapper ejecutará el archivo por lotes configurado y bloqueará dicho problema hasta que haya terminado:

Ejemplo del Registro de Valores de la Salida de Datos:
wrapper  | JVM parece estar colgada: Tiempo de Espera: Esperando una señal de la JVM. Reiniciando JVM.
wrapper  | JVM did not exit on request, termination requested.
wrapper  | Comando de Evento 'jvm_restart': Línea de Comando: cleanupTest.bat
wrapper  | Comando de Evento 'jvm_restart': Comando lanzado (pid: 664), bloqeado por hasta 15 segundos...
Limpiando por 10 segundos...
Proceso de Limpieza completo.
wrapper  | Comando de Evento: 'jvm_restart': El comando ha sido completado con código de salida: 0 
wrapper  | Comando de Evento: 'jvm_restart': El comando ha sido completado con código de salida: 0 Continuando.
wrapper  | Iniciando JVM...

Notificaciones a Través de Emails

Compatibilidad :3.3.0
Ediciones :Edición ProfesionaEdición Estándar (No Soportado)Edición de la Comunidad (No Soportado)
Plataformas :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/OSIBM z/Linux

Además de poder ejecutar comandos externos en respuesta a un evento de congelamiento también es posible configurar el Wrapper para enviar Notificaciones vía Email. Dicho email puede ser de una manera simple con la opción de incluir el registro de valores de la salida de datos más reciente.

Una notificación vía email del evento jvm_unexpected_exit puede configurarse de la siguiente manera:

Configuración del archivo "wrapper.conf"
wrapper.event.default.email.smtp.host=mail.ejemplo.com
wrapper.event.default.email.sender=wrapper-app@ejemplo.com
wrapper.event.default.email.recipient=sysadmin@ejemplo.com
wrapper.event.jvm_killed.email=TRUE
wrapper.event.jvm_killed.email.subject=Alerta! su aplicación ha sido eleminada!.
wrapper.event.jvm_killed.email.maillog=ATTACHMENT

Esto causará que un email como el que se muestra sea enviado cada vez que la JVM sea eliminada.

Eliminar la JVM usando "jvm_killed"
Asunto: Alerta! su aplicación ha sido eleminada!.
Para: sysadmin@ejemplo.com
De: wrapper-app@ejemplo.com

Notificación de Eventos del Java Service Wrapper 

Host: myserver
Nombre de aplicación:Testwrapper
         Ejemplo de la aplicación TestWrapper

Evento: jvm_killed
--
STATUS | wrapper  | 2013/10/18 11:16:59 | ...
INFO   | jvm 1    | 2013/10/18 11:17:04 | WrapperManager: WARNING: Making JVM appear to be hung...
ERROR  | wrapper  | 2013/10/18 11:17:35 | JVM parece estar colgada: Tiempo de Espera:  Esperando una señal de la JVM.  Reiniciando JVM. 
ERROR  | wrapper  | 2013/10/18 11:18:10 | JVM did not exit on request, termination requested.

También es agradable recibir buenas noticias, la siguiente configuración le dirá al Wrapper que envíe un segundo email cuando la JVM haya sido iniciada y la aplicación este funcionando. Este par de mensajes puede ser de mucha ayuda, manteniendo informado del estado de su servidor para decidir si debe estar alerta o disfrutar de su tiempo en la tranquilidad de su hogar.

Configuración del archivo "wrapper.conf"
wrapper.event.jvm_started.email=TRUE
wrapper.event.jvm_started.email.subject=Buenas noticias! La aplicación se ha recuperado.
wrapper.event.jvm_started.email.maillog=ATTACHMENT

Las notificaciones a través de email y eventos del sistema del Wrapper son de gran ayuda y configurables. Por favor visite la siguiente página Descripción de Eventos para más detalles.

Referencia: Congelamientos

El Java Service Wrapper proporciona un conjunto completo de propiedades de configuración que le permiten hacer que el Wrapper se adapte exactamente a sus necesidades. Por favor, lea la documentación de las propiedades individuales para ver todas las posibilidades además de los ejemplos mostrados anteriormente.