Java lui-même est un programme très volumineux dont la complexité approche celle d'un système d'exploitation. Bien qu'il soit généralement assez stable, comme tout programme, il rencontre occasionnellement des problèmes tels que des plantages, des gels, etc. Lorsqu'un processus d'application Java gèle, il peut être difficile de le détecter et d'en récupérer. Parce que le processus Java lui-même existe toujours en mémoire, de nombreuses applications de surveillance externes penseront qu'il est en vie même s'il a cessé de répondre.

Lorsqu'un gel de la JVM se produit, il est généralement constaté par les utilisateurs ou d'autres systèmes qui n'arrivent plus à interagir avec l'application. Une fois notifié du problème, souvent via une plainte d'un utilisateur, un administrateur système doit alors se connecter au serveur, tuer la JVM gelée et redémarrer l'application. Tout cela peut potentiellement prendre quelques heures si la personne qui doit effectuer le travail est sortie dîner.

Solution

La solution à ce problème consiste à disposer d'une application de surveillance, dotée d'une connaissance approfondie du fonctionnement de Java, à laquelle on peut faire confiance pour surveiller votre application Java 24 heures sur 24, 365 jours par an, et prendre automatiquement en charge les problèmes lorsqu'ils surviennent.

Le Java Service Wrapper contient plusieurs fonctionnalités de surveillance. L'une d'elles est la capacité de détecter lorsqu'une JVM a gelé. Le Wrapper surveille constamment une JVM et contient une logique avancée pour décider si une JVM est gelée ou non. Lorsqu'une JVM gelée est détectée, le Wrapper est alors capable de redémarrer automatiquement la JVM pour remettre le système en service avec un délai minimum. Le Wrapper peut ensuite envoyer une notification par e-mail aux administrateurs système au cas où ils souhaiteraient vérifier que tout est de nouveau opérationnel et fonctionne normalement.

Le Java Service Wrapper envoie périodiquement un ping au processus JVM (toutes les 5 secondes par défaut) et attend une réponse. Si la réponse n'arrive pas dans un délai configuré (30 secondes par défaut), alors le Wrapper déterminera qu'elle est gelée. Le Wrapper prend également en compte des éléments tels que la charge globale du système afin de s'assurer que les faux positifs sont réduits au minimum.

Lorsqu'un gel est détecté, le Wrapper enregistrera quelque chose comme ce qui suit dans le fichier journal :

Exemple de journal Gel et redémarrage :
jvm 1    | ...
wrapper  | JVM appears hung: Timed out waiting for signal from JVM.
wrapper  | JVM did not exit on request, terminated
wrapper  | Launching a JVM...
jvm 2    | WrapperManager: Initializing...
jvm 2    | ...

Le Wrapper vous aide à détecter les problèmes critiques, notamment :

Aperçu technique

La détection des gels est activée par défaut. Elle tentera d'envoyer un ping à la JVM toutes les 5 secondes puis d'expirer après 30 secondes sans réponse. Ces deux intervalles sont configurables. Si vous définissez la propriété wrapper.debug=TRUE, vous pourrez voir les pings dans le fichier journal. Dans cet exemple, le format du journal a été configuré pour inclure également les horodatages.

Exemple de journal des pings :
INFO   | jvm 1    | 2012/05/09 18:28:11 | ...
DEBUG  | wrapperp | 2012/05/09 18:28:13 | send a packet 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 | read a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 18:28:18 | send a packet 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: Send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 18:28:18 | read a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 18:28:21 |...

Détection des gels

Compatibilité :1.0.0
Éditions :Édition ProfessionnelleÉdition StandardÉdition Community
Plateformes :WindowsMac OSXLinuxAlpine LinuxFreeBSDSolarisIBM z/Linux

L'envoi de pings à la JVM est une fonctionnalité très légère, et il est recommandé de surveiller la JVM avec l'intervalle par défaut de 5 secondes. Selon votre application, ou dans les cas où le système est soumis à des charges externes très élevées, il peut être nécessaire d'allonger le délai d'attente du ping. Sachez que cela augmentera le temps nécessaire au Wrapper pour décider que la JVM est gelée.

Remarquez comment cet exemple montre que, lorsqu'une JVM gèle, elle cesse de répondre à tous les pings et le Wrapper initie un redémarrage :

Exemple de journal : gel et redémarrage.
DEBUG  | wrapperp | 2012/05/09 19:20:22 | send a packet 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 | read a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:27 | send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:31 | send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:36 | send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:40 | send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:44 | send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:49 | send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:53 | send a packet PING : ping
DEBUG  | wrapperp | 2012/05/09 19:20:58 | send a packet PING : ping
ERROR  | wrapper  | 2012/05/09 19:20:59 | JVM appears hung: Timed out waiting for signal from JVM.
ERROR  | wrapper  | 2012/05/09 19:21:00 | JVM did not exit on request, terminated

Essayer

Espérons que vous aurez du mal à reproduire un gel de JVM dans votre propre application Java. Pour faciliter les tests, le Wrapper est livré avec une application d'exemple TestWrapper qui peut être utilisée pour essayer cette fonctionnalité ainsi que de nombreuses autres.

Veuillez lancer l'application TestWrapper depuis une console en vous rendant dans la distribution Java Service Wrapper téléchargée et décompressée. Sous Windows, exécutez bin\TestWrapper.bat et sur les plates-formes UNIX, exécutez bin\testwrapper console.

Lorsque l'application d'exemple TestWrapper démarre, vous devriez voir un écran GUI simple avec plusieurs boutons sur le côté gauche. Cliquer sur le bouton Simulate JVM Hang fera en sorte que la JVM apparaisse gelée au Wrapper.

Exemple de journal : gel et redémarrage.
jvm 1    | TestWrapper: Showing dialog...
jvm 1    | WrapperManager: WARNING: Making JVM appear to be hung...
wrapper  | JVM appears hung: Timed out waiting for signal from JVM.
wrapper  | JVM did not exit on request, terminated
wrapper  | Launching a JVM...
jvm 2    | WrapperManager: Initializing...
jvm 2    | TestWrapper: Initializing...

Si vous souhaitez tester cela dans votre propre application Java, il est possible d'appeler WrapperManager.appearHung() pour entrer dans ce mode de test.

Réponse aux événements

Compatibilité :3.3.0
Éditions :Édition ProfessionnelleÉdition Standard (non prise en charge)Édition Community (non prise en charge)
Plateformes :WindowsMac OSXLinuxAlpine LinuxFreeBSDSolarisIBM z/Linux

Parfois, lorsqu'une application gèle ou plante, il ne suffit pas toujours de simplement la redémarrer. Si les fichiers temporaires n'ont pas été correctement nettoyés, ou si la base de données a été laissée dans un état instable, la nouvelle instance de l'application peut rapidement échouer avec des erreurs. Idéalement, l'application devrait être conçue pour être suffisamment robuste pour gérer ces échecs, mais ce n'est pas toujours possible. Dans de tels cas, nous avons besoin d'un moyen d'effectuer un nettoyage avant de lancer une nouvelle JVM.

Le Wrapper prend cela en charge grâce à l'utilisation des commandes d'événements. Il est possible d'indiquer au Wrapper d'exécuter une commande ou un script externe à divers moments.

Si vous consultez la sortie du journal de débogage, vous verrez occasionnellement des entrées Enqueue Event 'NNN'. Celles-ci indiquent le moment où les événements du Wrapper sont déclenchés. Dans le cas des redémarrages après la détection d'une JVM gelée, nous voulons lancer notre script de nettoyage avant le lancement de la nouvelle instance de JVM. L'événement jvm_restart sera utilisé.

Veuillez créer un fichier batch simple comme suit et le placer dans le même répertoire que le binaire du Wrapper. Cet exemple simule simplement une tâche de nettoyage de 10 secondes. Un véritable script serait plus intéressant.

Script d'exemple : « cleanupTest.bat »
@echo off
echo Cleaning up for 10 seconds...
rem use ping to cause a 10 second delay.
PING 1.1.1.1 -n 1 -w 10000 >NUL
echo All done cleaning up.

Ajoutez ensuite les propriétés suivantes à votre wrapper.conf

Fichier de configuration « 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

Désormais, lorsqu'un gel est détecté, le Wrapper exécutera le fichier batch configuré et se bloquera jusqu'à ce qu'il soit terminé :

Exemple de sortie du journal
wrapper  | JVM appears hung: Timed out waiting for signal from JVM.
wrapper  | JVM did not exit on request, terminated
wrapper  | Event Command 'jvm_restart': Command line: cleanupTest.bat
wrapper  | Event Command 'jvm_restart': Command launched (pid: 1188), blocking for up to 15 seconds...
Cleaning up for 10 seconds...
All done cleaning up.
wrapper  | Event Command 'jvm_restart': Command completed with exit code: 0
wrapper  | Event Command 'jvm_restart': Command completed with exit code: 0  Continuing.
wrapper  | Launching a JVM...

Notification par e-mail

Compatibilité :3.3.0
Éditions :Édition ProfessionnelleÉdition Standard (non prise en charge)Édition Community (non prise en charge)
Plateformes :WindowsMac OSXLinuxAlpine LinuxFreeBSDSolarisIBM z/Linux

En plus de la possibilité de lancer des commandes externes en réponse à un événement de gel, il est également possible de configurer le Wrapper pour envoyer un e-mail de notification. L'e-mail peut prendre la forme d'un simple avis, ou éventuellement inclure la sortie de journal la plus récente en pièce jointe.

Une notification par e-mail de l'événement jvm_unexpected_exit peut être configurée comme suit :

Fichier de configuration « wrapper.conf »
wrapper.event.default.email.smtp.host=mail.example.com
wrapper.event.default.email.sender=wrapper-app@example.com
wrapper.event.default.email.recipient=sysadmin@example.com
wrapper.event.jvm_killed.email=TRUE
wrapper.event.jvm_killed.email.subject=Oh no! The application was killed.
wrapper.event.jvm_killed.email.maillog=ATTACHMENT

Cela entraînera l'envoi d'un e-mail comme le suivant chaque fois que la JVM est tuée.

e-mail jvm_killed
Subject: Oh no! The application was killed.
To: sysadmin@example.com
From: wrapper-app@example.com

Java Service Wrapper Event Notification

Host: myserver
App Name: testwrapper
         TestWrapper Example Application

Event: jvm_killed
--

STATUS | wrapper  | 2012/05/15 18:23:42 | ...
INFO   | jvm 1    | 2012/05/15 18:23:47 | WrapperManager: WARNING: Making JVM appear to be hung...
ERROR  | wrapper  | 2012/05/15 18:24:24 | JVM appears hung: Timed out waiting for signal from JVM.
ERROR  | wrapper  | 2012/05/15 18:24:25 | JVM did not exit on request, terminated

Mais il est également bon de recevoir de bonnes nouvelles. La configuration suivante indiquera également au Wrapper d'envoyer un second e-mail chaque fois que la JVM a été lancée et que votre application est de nouveau opérationnelle. Cette paire d'e-mails peut être très utile pour vous tenir informé de l'état de votre serveur afin que vous puissiez décider s'il est possible de vous détendre et de profiter du reste du dîner.

votre wrapper.conf pour la configuration
wrapper.event.jvm_started.email=TRUE
wrapper.event.jvm_started.email.subject=Good news!  The applicaiton is back up.
wrapper.event.jvm_started.email.maillog=ATTACHMENT

Les systèmes d'e-mail et d'événements du Wrapper sont très puissants et configurables. Veuillez consulter la page Aperçu des événements pour plus de détails.

Référence : Gels

Le Java Service Wrapper fournit un ensemble complet de propriétés de configuration qui vous permettent d'adapter le Wrapper à vos besoins exacts. Veuillez consulter la documentation des propriétés individuelles pour découvrir toutes les possibilités au-delà des exemples présentés ci-dessus.