Apache2 Proxy Timeout

22

Ich habe Apache2 mit PHP + PHP-FPM konfiguriert gemäß:

http://wiki.apache.org/httpd/PHP-FPM

Ich schreibe ein Skript, dessen Ausführung auf einem internen Vhost viel Zeit in Anspruch nimmt, aber es läuft immer wieder aus, wenn das Skript in weniger als 30 Sekunden ausgeführt wird, läuft alles einwandfrei.

Mein Apache-Log sagt mir:

[Wed Apr 17 21:57:23.075175 2013] [proxy_fcgi:error] [pid 9263:tid 140530454267648] (70007)The timeout specified has expired: [client 58.169.202.172:49017] AH01075: Error dispatching request to :, referer:

Beim Versuch, das Skript auszuführen, erhalte ich eine 503 Service UnavailableAusführungszeit von genau 30 Sekunden. Logischerweise würde dies bedeuten, dass ich eine Timeout-Anweisung oder -Einstellung auf 30 Sekunden gesetzt habe, aber ich habe diese in der Konfiguration meines Vhost:

Timeout 600
<IfModule proxy_module>
    ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/home/pyrokinetiq/scripts/$1 timeout=600
    ProxyTimeout 600
</IfModule>

(php-fpm läuft für mich auf Port 9001)

Ich habe auch versucht, die Timeoutund ProxyTimeoutin zu platzierenhttpd.conf ohne Unterschied zu setzen.

Anscheinend gibt es irgendwo eine andere Timeout-Einstellung, die spezifisch ist mod_proxy_fcgi , aber ich kann sie nicht finden. Ich habe den Apache2 httpd vom offiziellen Tarball installiert, keiner der Mods scheint mit irgendwelchen Konfigurationsdateien geliefert worden zu sein.

Wenn jemand mich in die richtige Richtung lenken kann, wäre er sehr dankbar.

wyqydsyq
quelle

Antworten:

31

Ich habe dieses Problem endlich behoben, nachdem ich mehrere Konfigurationsparameter getestet hatte. Ich habe die Lösung zweimal getestet und dabei alle vorherigen Änderungen entfernt. Es wurde nur ein Parameter benötigt, um das Problem zu beheben.

Für die neuesten Versionen von httpd und mod_proxy_fcgi können Sie einfach timeout=das Ende der ProxyPassMatchZeile hinzufügen , zB:

ProxyPassMatch ^/(.+\.php.*)$ fcgi://127.0.0.1:9000/<docroot>/$1 timeout=1800

Bei älteren Versionen war es etwas komplizierter, zB:

<Proxy fcgi://127.0.0.1:9000>
  ProxySet timeout=1800
</Proxy>
ProxyPassMatch ^/(.+\.php.*)$ fcgi://127.0.0.1:9000/<docroot>/$1

Ich musste die Proxy-Direktive hinzufügen, um das Timeout auf 30 Minuten zu setzen. In einigen Anwendungen, normalerweise beim Betreiben von Datenbanken, kann die Ausführung von Routinen länger als 10 Minuten dauern. Ich habe das Timeout vorübergehend auf 30 Minuten festgelegt, um sicherzustellen, dass sie beendet werden. Besonders nützlich, wenn Sie den Installationsassistenten verwenden, der (meiner bescheidenen Meinung nach) zu viel Zeit in Anspruch nimmt.

Übrigens wurde die erste Eingabe, die mir bei der Lösung dieses Problems geholfen hat, in der folgenden URL-Adresse gefunden .

Jordi Ferran
quelle
1
Es sieht so aus, als ob dies in den letzten Versionen von Apache, AH00526, nicht funktioniert: ProxyPass / <Proxy> und ProxyPassMatch / <ProxyMatch> können nicht zusammen mit demselben Arbeiternamen verwendet werden
Stewart Adam
4
Ich habe das oben genannte Problem gelöst, indem ich einen Parameter 'timeout = 120' am Ende der ProxyPassMatch-Zeile hinzufügte.
Stewart Adam
@Palantir freut sich, es zu hören! Eingereicht als Antwort .
Stewart Adam
Zwei weitere Dinge, die ich brauchte: Zuerst müssen Sie "Timeout" und "ProxyTimeout" in Ihrer globalen Apache-Konfigurationsdatei so einstellen, dass sie länger sind als die anderen FPM-Timeouts. Zweitens hat mein FPM-Pool einen Unix-Socket abgehört und ich verwende SetHandler wie folgt: [SetHandler "Proxy: Unix: /var/run/php/example.com-php7.0-fpm.sock | fcgi: // localhost: 8000 "]. Aber <Proxy> stimmt mit dem fcgi: // localhost-Teil der SetHandler-Zeile überein (der Teil NACH dem | ..., der noch nicht einmal verwendet wird!) Und NICHT mit dem Unix: / var / run / part. So konfigurieren Sie Timeouts für die oben genannte Verwendung: <Proxy fcgi: // localhost: 8000> und nicht <Proxy unix: / var / run / ...
Professor Falken
9

Ich wollte darauf hinweisen, dass diese Antwort , obwohl sie für ältere Versionen hervorragend funktioniert, unter neueren Versionen von Apache 2.4 mit dem Fehlercode AH00526 funktioniert. ProxyPassund ProxyPassMatchoder <Proxy>und<ProxyMatch> können nicht zusammen mit demselben Arbeiternamen verwendet werden. Früher funktionierte das einwandfrei, daher weiß ich nicht, ob das durch das Design geändert wurde oder ob es sich um einen Fehler handelt.

In beiden Fällen können Sie dies beheben, indem Sie nur einen ProxyPassMatch mit dem Parameter 'timeout = 120' verwenden (oder einen beliebigen gewünschten Wert), z. B .:

ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/path/to/webroot/$1 timeout=120
Stewart Adam
quelle
6

Ich habe Apache 2.4.6, aber der Patch, mit dem ich das Problem beheben kann, ist in Apache> = 2.4.8 enthalten. Der Schlüssel hier ist, Ihre Ausgabe sofort zu starten, damit Apache (mod_proxy_fcgi) denkt, dass die Verbindung aktiv ist.

Zum Beispiel verwende ich PHP und die DB-Abfrage für meinen AJAX-Aufruf dauert> 30 Sekunden. Da ich weiß, dass die allgemeine Antwort "Content-Type: application / json" lautet, sende ich diesen Header sofort.

#1: Start output immediately
#Note: Sending the header is innocuous
#   it can be changed later using the $replace parameter
#   (see #3)
header( 'Content-Type: application/json' );

#2: Run slow query
mysql_query( "SELECT * FROM giant_table" );

#3: Change header as needed
header( 'Content-Type: application/csv', true );

#output content
Chris
quelle
2

Sollte das nicht sein:

<IfModule mod_proxy.c>

Stellen Sie sicher, dass die php.ini-Einstellung max_execution_time ebenfalls auf 600 gesetzt ist. (Überprüfen Sie phpinfo () auf der Live-Seite, um sicherzustellen, dass Sie den tatsächlich verwendeten Wert sehen.)

Wie Jenny sagte, stelle die PHP-FPM-Einstellung ein

request_terminate_timeout 610s

(Beachten Sie das s am Ende)

Wie Sie auf der Apache-Seite sehen können, müssen Sie nicht viel mit mod_proxy_fcgi selbst konfigurieren. http://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html

Aktivieren Sie die PHP-FPM-Debug-Protokollierung, damit Sie sehen können, wo das Zeitlimit liegt. http://php-fpm.org/wiki/Configuration_File (auch catch_workers_output aktivieren)

Und aktivieren Sie die Debug-Level-Protokollierung für die Module mod_proxy und mod_proxy_fcgi, da Sie Apache 2.4 verwenden. Sehr nette Funktion, schalten Sie nur die Module ein, die Sie benötigen: http://httpd.apache.org/docs/current/mod/core.html#loglevel

Wenn das nicht hilft, poste deine PHP-FPM-Konfigurationsdatei.

Vielleicht beendet ein Dämon als letztes Mittel einen lang andauernden Prozess?

troseman
quelle
2

Ich habe festgestellt, dass Sie PHP-FPM verwenden. Ich benutze es auch, aber mit Apache 2.4.6.

Unter der Annahme , dass das Problem seit einiger Zeit existiert hat, so scheint es zu sein , dass für den Timeout - Wert mod_proxy_fcgiist hart codiert . Ich habe aufgeschrieben, was ich hier gefunden habe

Misterich
quelle
1

Da Sie die Zeitlimit-Einstellungen in Apache korrigiert haben, sollte dies nicht das Problem sein. Der zweite Ort, an dem Sie nachsehen müssen, ist jede Netzwerkausrüstung. Da Sie jedoch einen Proxy für Ihren eigenen Server einrichten, ist dies ebenfalls unwahrscheinlich. Der verbleibende Ort ist also der Backend-Server.

Suchen Sie nach der Konfigurationsdatei für php-pfm

; This is a hard kill switch on php execution.  It ignores the
; max_execution_time that can be set/changed with php_ini.  Basically
; it avoids timeout issues between apache and php-fpm.
request_terminate_timeout=30

Dies sollte mit der Zeitüberschreitungseinstellung in Apache identisch sein oder geringfügig darunter liegen.

Jenny D sagt Reinstate Monica
quelle
1
Ich habe den request_terminate_timeoutmod_proxy_fcgi
Wert
0

Setzen Sie zusätzlich zum Timeout die Option "Enablereuse" auf "Off". Ich stellte fest, dass einige Anfragen nach lang laufenden Skripten korrekt funktionierten und andere vorzeitig beendet wurden.

ctlq
quelle
0

Dieser Beitrag hat das Ganze für mich verändert.

Es sieht so aus, als würde das mod_reqtimeout von Apache nicht den Standardwert verwenden.

Fügen Sie Ihrer httpd.conf- Datei die folgenden Zeilen hinzu :

<IfModule reqtimeout_module>
  RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
Frosty Z
quelle