Schlagwort-Archive: Monit

PHP: Überwachung von Prozessen

In einigen Fällen kann es erforderlich sein, dass ein PHP-Skript nicht mehr wie gewohnt per Request aufgerufen werden soll um dann seine Arbeit erledigt, sondern das es ständig auf dem Server läuft und auf Events wartet. Ein typisches Beispiel hierfür wäre der Client eines Queue-Systems, der beständig auf neue Nachrichten wartet, um sie dann abzuarbeiten.

Beim Auftreten eines Fehlers oder eines Server-Neustarts dürfen sich solche Skripte natürlich nicht einfach nur mit einer Fehlermeldung beenden. Im Gegenteil: Ein solches Verhalten würde das gesamte System zum Erliegen bringen und die Abarbeitung neuer Aufträge solange unterbrechen, bis der Fehler manuell behoben und das Skript wieder gestartet worden ist. Somit muss das Skript also ständig von einem externen Programm überwacht werden, was nicht nur den Fehler erkennt sondern den Prozess auch automatisch neu starten kann.

Für solche Überwachungs-Aufgaben bietet sich beispielsweise Monit an. Monit ist ein einfaches Programm, mit dem eine Vielzahl von Serverdaten und Diensten überwacht werden kann.

Damit Monit unseren Prozess erst einmal überhaupt erkennen kann muss unser Skript beim Starten ein PID-File unter /var/run anlegen. Die nachfolgende Funktion übernimmt diese Aufgabe und legt bei jedem Start eine neue Datei mi dem Namen des Skriptes und der Endung .pid an.

Wenn unser Skript beispielsweise unter /var/www/apache/test_client.php liegt wird also ein PID-File test_client.pid unter /var/run angelegt. In das PID-File wird zudem die aktuelle ProzessID geschrieben, welche unser Skript zum Start zugewiesen bekommen hat.

Achtung: Der User, der das Skript startet muss auch das Recht haben, um nach /var/run schreiben zu dürfen.

Zum starten des Skripts habe ich ein einfaches Shell-Skript test_client.sh angelegt, über das unser Skript getartet sowie ausgegebene Meldungen und Fehler protokolliert werden können.

Achtung: Das Shell-Skript muss ausführbar sein bzw. das Ausführen-Recht besitzen.

Im nächsten Schritt muss Monit die neue Überwachungsaufgabe konfiguriert werden. Dies geschieht, indem wir unter /etc/monit/conf.d/ eine neue Konfigurationsdatei (z.B. test_client.conf) anlegen, in der wir die Aufgabe definieren.

Damit ist alles konfiguriert und wir können zum ersten Test schreiten.

Hierfür starten wir Monit mit /etc/init.d/monit start und prüfen, ob unser Skript nun in der Prozess-Liste auftaucht. (ps aux | grep test_client)

Im zweiten Schritt testen wir, ob unser Skript im Falle eines Fehlers auch automatisch neu gestartet werden würde. Dafür beenden wir die Ausführung des laufenden Skripts mit kill. (kill -9 PID-ID aus der Ausgabe von ps aux) Nach einigen Sekunden sollte Monit das Fehlen des Prozesses erkannt haben und das Skript neu starten. (ps aux | grep test_client)

Wichtig beim Testen: Wenn im zu überwachenden PHP-Skript ein Fehler enthalten ist (Parse-Error, etc.) startet Monit es nur die Anzahl an Restarts, die in der Config-Datei angegeben worden sind. Wenn diese Anzahl überschritten worden ist hilft auch ein Neustart von Monit nicht weiter, da dieses seine Fehlversuche in der Datei /var/lib/monit/state speichert. Es startet das PHP-Skript so lange nicht mehr neu, bis diese Datei gelöscht worden ist. Danach muss Monit via /etc/init.d/moint restart neu gestartet werden.

Damit ist nun sichergestellt, dass sowohl bei einem Server-Neustart als auch bei einem Fehler unser Skript automatisch neu gestartet wird.

Dieses Beispiel deckt natürlich noch lange nicht alle Aspekte ab. Beispielsweise wollen wir trotz der nun geschaffenen Ausfallsicherheit darüber informiert werden, wann und warum unser Skript neu gestartet werden mußte. Auch will der Monit-Dienst selbst überwacht werden (beispielsweise mit Nagios) um sicherzustellen, dass er immer aktiv ist.

Darüber hinaus ergeben sich durch das ständig laufende PHP-Skript Änderungen im Systemverhalten, wenn beispielsweise zum Start des PHP-Skripts eine Datenbankverbindung aufgebaut wird. Dann muss das Skript selbständig erkennen, ob diese Verbindung noch besteht und ggf. erst eine neue Verbindung herstellen, bevor die eigentliche Abarbeitung erfolgen kann. Es gibt also noch eine Menge zu tun. 😉