php CLI und das „too many open files“ Problem

imagesFür ein internes Projekt habe ich eine CLI-Anwendung mit php (5.5) gebaut, welche als Background-Prozess läuft. Im Zuge der Ausführung werden mehrere weitere Threads (pthreads) erzeugt.

Es gibt bei dieser Art der Anwendung einige Fallstricke, die der Tatsache geschuldet sind, dass sich das Skript quasi nie beendet. Somit muss man sich um das Aufräumen selbst kümmern, also DB-Connections schließen, Variablen möglichst wieder unsetten bzw. leeren… All das was eigentlich nach dem Beenden eines Skripts automatisch abläuft.

Das Ganze erfordert schone ein wenig Disziplin im Umgang mit den Ressourcen. Schlimm ist es aber, wenn manche Module einfach nicht für diesen Modus ausgelegt sind!

In unserem Fall betrifft dies folgende Module: mssql und opendir.

Beide Module haben (eventl auch im Zusammenspiel mit threaded php) ein Problem mit Ihren entsprechenden close-Funktionen: Beide funtkionieren schlichtweg nicht!

Sowohl mssql_close($handle) als auch closedir($handle) hinterlassen weiterhin offene Handles, was bei längerer Laufzeit dazu führt, dass das Limit für geöffnete Dateien des ausführenden Users überschritten wird und php mittels Fatal-Error aussteigt. Super ärgerlich das Ganze, zumal beide Funktionen brav ein „TRUE“ als Rückgabewert liefern.

Problemerkennung

Natürlich ist der o.g. Fatal Error schon Hinweis genug, aber man kann auf der Konsole am Schnellsten die Anzahl der offenen „Dateien“ (unter UNIX ist nahezu alles eine Datei, also Sockets, Netzwerkverbindungen, …) eines Users abfragen:

lsof -u USERNAME | wc -l

Der Befehl listet einfach die Zeilen der Ausgabe von lsof (offene Handles)

Wenn man dies zur Laufzeit öfter mal ausführt, kann man Unregelmäßigkeiten recht schnell finden. Wenn das Skript nicht gerade komplette Verzeichnisbäume ausliesst, sollte die Zahl nahezu konstant bleiben. Bei unseren Fehlern wuchs die Zahl um ca. 5 Files / 10 Sek.!!!

Problembehebung

Am Einfachsten ist es bei dem opendir-/closedir-Problem: einfach die Directory-Klasse nutzen. Hier scheint alles perfekt zu funktionieren! Alle Handles werden geschlossen…

Problematisch ist aber die mssql-Extension. Hier hat es erst funktioniert, als wir auf einen pconnect umgestiegen sind, unter Inkaufnahme der persistenten Verbindung (besser eine Verbindung, als x offene Links!)

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *