
Ich versuche, Apache + PHP-FPM einzurichten, wir haben jedoch ein lange laufendes Skript, das ausgeführt wurde und schließlich eine Zeitüberschreitung aufwies, wodurch die Verbindung zwischen Apache und FPM unterbrochen wurde und letztendlich die gesamte Site zum Absturz gebracht wurde ...
Gibt es eine Möglichkeit, den Absturz der gesamten Site zu verhindern, wenn das --idle-timeout erreicht wird?
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -idle-timeout 18000 -pass-header Authorization
Antwort1
Die Apache-Anfrage an php-fpmwird abgebrochen, wenn das Timeout erreicht ist. Also auch für den Benutzer. Wenn Sie möchten, dass der Endkunde eine Antwort erhält, fallen Ihnen drei Möglichkeiten ein:
- Erhöhen Sie Ihren Timeout-Wert (da Ihre PHP-Anwendung langsamer ist)
- Versuchen Sie, Ihre PHP-Anwendung für diese Anfrage schneller zu machen
- Lassen Sie Ihre PHP-Anwendung die benötigte Zeit berechnen und mit einer Fehlermeldung reagieren, wenn es länger dauert als Ihr Timeout-Wert
Lösung Nr. 2 wäre meiner Meinung nach die übliche Wahl der Entwickler.
Antwort2
Lang laufende Skripte sollten nicht vom Browser/Apache ausgeführt werden. Sie sollten sie im Hintergrund mit PHP CLI statt mit FPM ausführen. CLI-Skripte haben keine Zeitüberschreitung und stören den Apache-Betrieb nicht.
Sie können die regelmäßige Ausführung des Skripts entweder mithilfe von Cronjobs planen oder es vom Browser aus auslösen lassen, indem Sie beispielsweise eine temporäre Datei schreiben (legen Sie beispielsweise eine Datei mit dem Namen run_script
in Ihr Website-Verzeichnis und entfernen Sie sie am Ende Ihres Skripts) oder ein Flag in einer Datenbank oder einem anderen Backend setzen.
Wenn Sie sich für die zweite Möglichkeit entscheiden, benötigen Sie noch immer einen Cronjob (der einmal pro Minute ausgeführt werden kann), der die Existenz dieses Datei-/Datenbankeintrags überprüft und das Skript auslöst, wenn er gefunden wird (Sie könnten auch einen Listener erstellen, der dies ständig statt einmal pro Minute überwacht, aber das ist ziemlich aufwändig und für die meisten Anwendungsfälle wahrscheinlich übertrieben).
Sobald es ausgelöst wurde, senden Sie Ihren Benutzern lediglich eine Benachrichtigung wie „Warten Sie, wir bearbeiten Ihre Anfrage. Bitte schauen Sie in ein paar Minuten noch einmal vorbei.“ zurück. Auf diese Weise müssen sie ihren Browser auch nicht geöffnet lassen, um die Anfrage auszuführen, und können in der Zwischenzeit einfach andere Dinge tun.