Java als eine Sprache wurde mit dem Ziel entwickelt, es für Usercode unmöglich zu machen, einen Anwendungsabsturz zu verursachen. Jeder Fehler würde in einen Ausnahmefehler resultieren, dessen Ausgabe gleichzeitig abgefangen und dann auf geeignete Weise erledigt würde. Die Realität, wie jeder langjährige Java-Entwickler oder Systemadministrator weiß, ist, dass selbst die Java Virtuelle Maschine (JVM) abstürzen kann, und auch abstürzt. Dies ist weil die JVM als Programm selbst in nativen Code geschrieben ist, und wie jedes sehr große komplexe Programm, hat die JVM auch Bugs.

Wie jedes andere Programm, wenn Java abstürzt, beendet es sich und verschwindet mit Ihrer Anwendung. Dies kann desaströs sein, wenn die Anwendung für das Unternehmen kritisch ist. Die Anwendung kann beendet sein und der Ausfall nicht bemerkt werden bis der Kunde das nächste Mal Ihre Webseite besucht. Oder die Versandabteilung ruft an, weil sie seit ein paar Stunden keine Versandaufträge erhalten haben. Sobald festgestellt wurde, dass die Anwendung beendet ist, kann es womöglicherweise eine oder zwei Stunden länger dauern bis der Systemadministrator erscheint und einen Neuestart durchführt.

Lösung

Die Lösung auf dieses Problem ist es, eine Anwendung zu haben, die das Überwachen übernimmt und mit einem guten Wissen darüber, wie Java funktioniert. Eine Überwachung Ihrer Java-Anwendung von 24 Stunden am Tag, 365 Tage im Jahr soll vertraut werden; inklusive der automatischen Problembehandlung. Der Java Service Wrapper enthält verschiedene Monitoring-Features; eines von ihnen ist die Fähigkeit, festzustellen, wann eine JVM abgestürzt ist. Es überwacht dauerhaft die JVM und ist imstande, umgehend nach einem Absturz der JVM dies auch zu erkennen. Sobald ein Absturz entdeckt wurde, führt der Wrapper automatisch einen Neustart der JVM durch, um das System wieder hochzufahren und mit einer minimalen Verzögerungszeit zum Laufen zu bringen. Schließlich können Sie eine Email-Benachrichtigung einstellen, die dem Systemadministrator gersandt wird, um sicherzustellen, dass alles wieder normal läuft.

Die vollständige Absturzentdeckung, Wiederherstellung und der Benachrichtigungsprozess werden alle durch den Java Service Wrapper automatisch behandelt, ohne dass es den Eingriff einer Bedienungsperson bedarf. Sobald ein Absturz erkannt wurde, wird der Wrapper etwas wie folgt aufzeichnen: Die log-Datei:

Logbeispiel für einen Absturz und einen Neustart:
jvm 1    | ...
jvm 1    | #
jvm 1    | # A fatal error has been detected by the Java Runtime Environment:
jvm 1    | #
jvm 1    | #  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000001800074ff, pid=856, tid=704
jvm 1    | #
jvm 1    | # JRE version: 6.0_24-b07
jvm 1    | # Java VM: Java HotSpot(TM) 64-Bit Server VM (19.1-b02 mixed mode windows-amd64 compressed oops)
jvm 1    | # Problematic frame:
jvm 1    | # C  [wrapper.dll+0x74ff]
jvm 1    | #
jvm 1    | # An error report file with more information is saved as:
jvm 1    | # C:\myapp\bin\hs_err_pid856.log
jvm 1    | #
jvm 1    | # If you would like to submit a bug report, please visit:
jvm 1    | #   http://java.sun.com/webapps/bugreport/crash.jsp
jvm 1    | # The crash happened outside the Java Virtual Machine in native code.
jvm 1    | # See problematic frame for where to report the bug.
jvm 1    | #
wrapper  | JVM exited unexpectedly.
wrapper  | Launching a JVM...
jvm 2    | WrapperManager: Initializing...
jvm 2    | ...

Während die oben genannte Nachricht etwas kryptisch erscheinen mag, ist es der Versuch der JVM, Sie mit Informationen über den Absturz zu versorgen. Weil diese Ausgabe als Speicherabbild auf einer sehr niedrigen Ebene der Konsole ausgegeben wird, ist es für alle auf Java basierenden Logging-Tools unmöglich, diese Information aufzuzeichnen. Bitte beachten Sie, dass der Wrapper in der Lage ist, 100% der Konsolenoutputs der JVM zu erfassen und sicherzustellen, dass alles in der Log-Datei erhalten ist. Ohne den Wrapper würde nicht nur Ihre Anwendung nicht mehr betriebsbereit sein, aber auch die Erklärung, was geschehen ist, würde verloren gehen.

Idealerweise sollte jeder Absturz so bald wie möglich behoben werden, um zukünftige Abstürze zu vermeiden. Jedoch kann es, da Abstürze häufig durch unklare Wechselwirkungen zwischen perfekt gültigen Java-Code and Bugs in der JVM selbst zustande kommen, Wochen oder Monate für Entwickler dauern, um das Problem zu identifizieren und einen Workaround dafür zu finden.

Der Wrapper hilft Ihnen, kritische Probleme inklusive der Folgenden zu entdecken:

Technische Übersicht

Absturzerkennung ist im Wrapper stetig eingeschaltet, da das Überprüfen von Abstürzen keine zusätzliche Last auf die JVM oder das System darstellt. Da Systemabstürze entweder erfolgen oder ausbleiben, gibt es keine Möglichkeit, diese Erkennung auzuschalten. Es ist jedoch möglich zu steuern, was der Wrapper tut, sobald ein Absturz erfolgt ist.

Sobald ein Absturz erkannt wurde, wartet der Wrapper zuerst einen Moment (Standardmäßig 5 Sekunden) um dem Systemspeicher und -ressourcen zu erlauben in den Normalzustand zurückzukehren, und dann nachdem konfigurierte Benachrichtigungen erfolgt sind, eine neue JVM-Instanz zu starten, um Ihre Anwendung wieder ohne Verzögerung zum Laufen zu bringen. Wie unten beschrieben, ist es möglich, diese Funktion des automatischen Neustarts, wenn notwendig, auszuschalten.

Testen

Hoffentlich wird es Ihnen schwerfallen, einen Absturz der JVM in Ihrer Java-Anwendung nachzustellen. Um dieses einfach auszutesten, wird der Wrapper mit einem Link zu einer TestWrapper Beispielanwendung ausgeliefert, die benutzt werden kann, um dieses und viele andere Features zu testen.

Starten Sie bitte die TestWrapper-Anwendung von einer Konsole, indem Sie die heruntergeladene und erweiterte Java Service Wrapper Distribution öffnen. Auf Windows starten Sie bin\TestWrapper.bat und auf UNIX-Plattformen rufen Sie bin\testwrapper console auf.

Sobald die TestWrapper-Beispielanwendung hochstartet, sollten Sie einen einfachen GUI-Bildschirm mit verschiedenen Schaltflächen auf der Seite links unten sehen. Klicken Sie auf die Native Access Violation-Schaltfläche, um die JVM zu veranlassen, gegenüber dem Wrapper abgestürzt zu erscheinen.

Beispiellog: Absturz und Neustart.
jvm 1    | TestWrapper: Showing dialog...
jvm 1    | WrapperManager: WARNING: Attempting to cause an access violation...
jvm 1    | #
jvm 1    | # A fatal error has been detected by the Java Runtime Environment:
jvm 1    | #
jvm 1    | #  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000018000746f, pid=1632, tid=2284
jvm 1    | #
jvm 1    | # JRE version: 6.0_24-b07
jvm 1    | # Java VM: Java HotSpot(TM) 64-Bit Server VM (19.1-b02 mixed mode windows-amd64 compressed oops)
jvm 1    | # Problematic frame:
jvm 1    | # C  [wrapper.dll+0x746f]
jvm 1    | #
jvm 1    | # An error report file with more information is saved as:
jvm 1    | # C:\myapp\bin\hs_err_pid856.log
jvm 1    | #
jvm 1    | # If you would like to submit a bug report, please visit:
jvm 1    | #   http://java.sun.com/webapps/bugreport/crash.jsp
jvm 1    | # The crash happened outside the Java Virtual Machine in native code.
jvm 1    | # See problematic frame for where to report the bug.
jvm 1    | #
wrapper  | JVM exited unexpectedly.
wrapper  | Launching a JVM...
jvm 2    | WrapperManager: Initializing...

Wenn Sie wünschen, dies in Ihrer eigenen Java-Anwendung auszutesten, ist es möglich, folgende Methode aufzurufen WrapperManager.accessViolationNative(), um einen beabsichtigten Systemabsturz zu verursachen.

Troubleshooting

Javas Absturzberichte mögen auf den ersten Blick als nicht besonders hilfreich erscheinen. Aber wenn Sie wissen nach was Sie suchen müssen, können sie Sie mit sehr nützlicher Information versorgen, die für die Problemlösung gebraucht wird.

In dem oben genannten Beispiel sagt uns die JVM, dass ein detaillierter Fehlerbericht auf die Festplatte als C:\myapp\bin\hs_err_pid856.log abgespeichert wurde. Die Analyse von diesen Absturzberichten wird nicht im Rahmen dieses Dokuments behandelt, aber wir empfehlen Ihnen, einen Blick auf folgenden Troubleshooting-Guide der Oracle-Website zu werfen. Wenn Sie wirklich mehr darüber erfahren wollen, dann kann folgender Link Crash-Kurs auf JVM-Crashanalyse ziemlich nützlich sein.

Verzögerung beim Neustarten

Kompatibel :2.2.9
Editionen :Professional EditionStandard EditionCommunity Edition
Betriebssysteme :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/OSIBM z/Linux

Sobald ein Systemabsturz erkannt wurde, wird der Wrapper standardmäßig 5 Sekunden warten, um Speicher und System-Ressourcen, die von der abgestürzten JVM in Benutzung waren, die Möglichkeit zu geben, vom System wiederhergestellt zu werden, bevor eine Ersatz-JVM gestartet wird. Wenn eine neue JVM zu schnell neu gestartet wird, dann kann abhängig von den Gründen des Systemabsturzes, die neue JVM in Probleme geraten oder langsam starten.

Die Zeitspanne, die das System braucht, etwas zu erledigen, hängt von einer Anzahl von Faktoren ab, inklusive der Gesamtsystemlast und der Anwendungsgröße, die in der abgestürzten JVM in Benutzung war. Während es möglich ist, diese Verzögerung zu verkürzen, wurde festgestellt, dass der Standardwert eine sichere Zeitdauer lang betragen muss. Die Verzögerung, bevor eine neue JVM neu gestartet wird, kann durch Nutzung des folgenden Links der wrapper.restart.delay Eigenschaft überwacht werden.

Konfigurationsbeispiel: Wartezeit für das Neustarten der JVM (5 Sekunden)
wrapper.restart.delay=5

Deaktivieren von Neustarts

Kompatibel :3.3.4
Editionen :Professional EditionStandard EditionCommunity Edition
Betriebssysteme :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/OSIBM z/Linux

In den meisten Fällen, wenn eine JVM abstürzt, möchten Sie diese neu gestartet bekommen. Es gibt jedoch gewisse Fälle, in denen zuerst ein manuelles Löschen/Aufräumen oder andere Aktionen nötig sind. In diesen Fällen kann die Neustart-Funktion des Wrappers unter Benutzung der wrapper.disable_restarts.automatic Eigenschaft ausgeschaltet werden.

Konfigurationsbeispiel: (Ausschalten von Neustart)
wrapper.disable_restarts.automatic=TRUE

Antworten auf Ereignisse

Kompatibel :3.3.0
Editionen :Professional EditionStandard Edition (Not Supported)Community Edition (Not Supported)
Betriebssysteme :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/OSIBM z/Linux

Manchmal wenn eine Anwendung einfriert oder abstürzt, ist es nicht immer einfach, diese neu zu starten. Wenn temporäre Dateien nicht ordnungsgemäß aufgeräumt werden, oder die Datenbank in einem nicht stabilen Zustand gelassen wird, kann es sein, dass die neue Anwendungsinstanz schnell mit Fehlern abstürzen kann. Idealerweise sollte die Anwendung so bestimmt sein, dass sie stabil genug ist, um mit diesen Abstürzen umzugehen, aber dies ist nicht immer möglich. In solchen Fällen müssen wir gewisse Aufräumarbeiten durchführen, bevor eine neue JVM gestartet wird.

Der Wrapper unterstützt dies durch die Nutzung der Ereignisbefehle. Es ist möglich, dem Wrapper zu sagen, dass er ein externes Kommando oder ein Skript zu verschiedenen Zeiten ausführen soll.

Wenn Sie in das Debug-Ausgabelog sehen, werden Sie gelegentliche Enqueue Event 'NNN' Einträge sehen. Diese zeigen das Timing bezüglich wann die Wrapper Ereignisse gestartet wurden. Im Falle von Neustarts, nachdem eine abgestürzte JVM entdeckt wurde, wollen wir das Aufräum- Skript starten, bevor die neue JVM-Instanz gestartet wird. Das jvm_restart Ereignis wird benutzt werden.

Erstellen Sie bitte eine einfache Batch-Datei wie folgt und platzieren Sie sie in das gleiche Verzeichnis, in welches sich die Wrapper-Programmdatei befindet. Dieses Beispiel simuliert auf einfache Weise ein 10 Sekunden dauernde Aufräum-Aufgabe. Eine wirkliche Skriptdatei ist interessanter.

Beispielskript: "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.

Fügen Sie als nächsten Schritt folgende Eigenschaften der Datei wrapper.conf zu.

Konfigurationsdatei: "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

Nun, wenn ein Absturz entdeckt wurde, wird der Wrapper die konfigurierte Batch-Datei ausführen und sie blockieren bis sie vervollständigt wurde:

Log Output Example
jvm 1    | # The crash happened outside the Java Virtual Machine in native code.
jvm 1    | # See problematic frame for where to report the bug.
jvm 1    | #
wrapper  | JVM exited unexpectedly.
wrapper  | Event Command 'jvm_restart': Command line: cleanupTest.bat
wrapper  | Event Command 'jvm_restart': Command launched (pid: 965), 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...

Email-Benachrichtigung

Kompatibel :3.3.0
Editionen :Professional EditionStandard Edition (Not Supported)Community Edition (Not Supported)
Betriebssysteme :WindowsMac OSXLinuxIBM AIXFreeBSDHP-UXSolarisIBM z/OSIBM z/Linux

Zusätzlich zu der Fähigkeit, externe Befehle als Antwort auf ein Ereignis des Systemabsturzes zu starten, ist es auch möglich, den Wrapper für die Versendung einer Benachrichtungsemail zu konfigurieren. Die Email kann die Form einer einfachen Mitteilung annehmen, oder optional die neueste Logausgabe als Emailanhang beinhalten.

Eine Email-Benachrichtigung des jvm_unexpected_exit Ereignisses kann wie folgt konfiguriert werden:

Konfigurationsdatei "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_unexpected_exit.email=TRUE
wrapper.event.jvm_unexpected_exit.email.subject=Oh no! The application crashed!
wrapper.event.jvm_unexpected_exit.email.maillog=ATTACHMENT

Dies veranlasst, eine Email wie die Folgende zu versenden, wann immer die JVM abstürzt.

jvm_unexpected_exit Email
Subject: Oh no! The application crashed!.
To: sysadmin@example.com
From: wrapper-app@example.com

Java Service Wrapper Event Notification

Host: myserver
App Name: testwrapper
         TestWrapper Example Application

Event: jvm_unexpected_exit

INFO   | jvm 1    | 2012/09/13 16:00:00 | ...
INFO   | jvm 1    | 2012/09/13 16:00:00 | # The crash happened outside the Java Virtual Machine in native code.
INFO   | jvm 1    | 2012/09/13 16:00:00 | # See problematic frame for where to report the bug.
INFO   | jvm 1    | 2012/09/13 16:00:00 | #
ERROR  | wrapper  | 2012/09/13 16:00:00 | JVM exited unexpectedly.

Aber es ist auch gut, gute Nachrichten zu bekommen. Die folgende Konfiguration informiert auch den Wrapper darüber, eine zweite Email zu versenden, wann immer die JVM gestartet wurde und Ihre Anwendung wieder läuft. Dieses Paar an Emails kann sehr nützlich sein, um Sie über den Zustand des Servers auf dem Laufenden zu halten.

Konfigurationsdatei "wrapper.conf"
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

Die Email- und Ereignis-Systeme des Wrappers sind sehr leistungsstark und konfigurierbar. Bitte sehen Sie für mehr Details auf die Seite Ereignis-Übersicht.

Wiederherstellung des Dienstes

Kompatibel :3.5.5
Editionen :Professional EditionStandard EditionCommunity Edition (Not Supported)
Betriebssysteme :WindowsMac OSX (Not Supported)Linux (Not Supported)IBM AIX (Not Supported)FreeBSD (Not Supported)HP-UX (Not Supported)Solaris (Not Supported)IBM z/OS (Not Supported)IBM z/Linux (Not Supported)

Der Wrapper ist verantwortlich und imstande, mit verschiedenen Arten von Java-Abstürzen umzugehen. Während der Wrapper-Prozess sich selbst als sehr stabil erwiesen hat, behandelt dieser Abschnitt, wie eine Recovery von einem Absturz des Wrapper-Prozesses selbst erfolgen kann.

Der Windows Dienst Manager is verantwortlich für das Starten, Stoppen und Überwachen aller Windows-Dienste, inklusive des Wrappers selbst. Es ist möglich, den Wrapper so zu konfigurieren, dass er den Windows Dienst Manager darüber informiert, was im Falle eines Wrapper-Absturzes zu tun ist. Diese Wiederherstellung-Features können konfiguriert werden, indem die verfügbaren Eigenschaften der Windows Dienst Wiederherstellung Abschnitts benutzt werden. Bitte sehen Sie eine Schritt-für-Schritt-Vorgehensweise anhand eines Beispiels der wrapper.ntservice.recovery.<x>-Eigenschaft.

Verweis: Crashes

Der Java Service Wrapper bietet einen kompletten Satz an Konfigurationseigenschaften an, die es Ihnen ermöglichen, dass der Wrapper genau Ihre Bedürfnisse abdeckt. Sehen Sie bitte in die Dokumentation bezüglich der einzelnen Eigenschaften, um alle Möglichkeiten über die obengenannten Beispiele hinaus zu sehen.