Limit czasu serwera proxy Apache2

23

Mam Apache2 z PHP + PHP-FPM skonfigurowany zgodnie z:

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

Piszę skrypt, który będzie długo działał na wewnętrznym Vhostie, ale wciąż mija limit czasu, wszystko działa bezbłędnie, jeśli skrypt wykona się w czasie krótszym niż 30 sekund.

Mój dziennik Apache mówi mi:

[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:

Podczas próby uruchomienia skryptu dostaję 503 Service Unavailabledokładnie 30 sekund czasu wykonania. Logicznie oznaczałoby to, że mam dyrektywę lub ustawienie limitu czasu ustawione na 30 sekund, ale mam je w konfiguracji mojego Vhosta:

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

(php-fpm działa dla mnie na porcie 9001)

Próbowałem również umieszczenie Timeouti ProxyTimeoutw httpd.confbez różnicy.

Wygląda na to, że istnieje inne ustawienie limitu czasu, które jest specyficzne mod_proxy_fcgi, ale nie mogę go znaleźć. Zainstalowałem httpd Apache2 z oficjalnego tarballa, żaden z modów nie wydaje się mieć żadnych plików konfiguracyjnych.

Byłbym bardzo wdzięczny, gdyby ktokolwiek mógł skierować mnie w dobrym kierunku.

wyqydsyq
źródło

Odpowiedzi:

32

W końcu naprawiłem ten problem po przetestowaniu kilku parametrów konfiguracyjnych. Testowałem rozwiązanie dwa razy, usuwając wszystkie poprzednie zmiany. Potrzebowałem tylko jednego parametru, aby go naprawić.

W najnowszych wersjach httpd i mod_proxy_fcgi możesz po prostu dodać timeout=na końcu ProxyPassMatchwiersza, np .:

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

W przypadku starszych wersji było to nieco bardziej skomplikowane, np .:

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

Musiałem dodać dyrektywę proxy, aby ustawić limit czasu na 30 minut. W niektórych aplikacjach, zwykle podczas działania bazy danych, istnieją procedury, których wykonanie może potrwać dłużej niż 10 minut. Czasowo ustawiłem limit czasu na 30 minut, aby mieć pewność, że się zakończą. Szczególnie przydatny podczas korzystania z kreatora instalacji, który zajmuje zbyt dużo czasu (moim skromnym zdaniem).

Nawiasem mówiąc, wstępne dane, które pomogły mi rozwiązać ten problem, zostały znalezione pod następującym adresem URL .

Jordi Ferran
źródło
1
Wygląda na to, że ten problem zepsuł się w ostatnich wersjach Apache, AH00526: ProxyPass / <Proxy> i ProxyPassMatch / <ProxyMatch> nie mogą być używane łącznie z tym samym nazwiskiem pracownika
Stewart Adam
4
Rozwiązałem powyższe, dodając parametr „limit czasu = 120” na końcu wiersza ProxyPassMatch.
Stewart Adam
@Palantir miło to słyszeć! Przesłane jako odpowiedź .
Stewart Adam
Potrzebowałem jeszcze dwóch rzeczy: Po pierwsze, musisz ustawić „Limit czasu” i „ProxyTimeout” w globalnym pliku konfiguracyjnym apache, aby był dłuższy niż inne limity FPM. Po drugie, moja pula FPM nasłuchiwała na gnieździe unixowym i używam SetHandler w taki sposób: [SetHandler "proxy: unix: /var/run/php/example.com-php7.0-fpm.sock | fcgi: // localhost: 8000 ”]. Ale <Proxy> pasuje do części fcgi: // localhost linii SetHandler (część PO | ... która nawet nie jest faktycznie używana!), A NIE unix: / var / run / part. więc aby skonfigurować limity czasu dla powyższego użycia: <Proxy fcgi: // localhost: 8000> a nie <Proxy unix: / var / run / ...
Professor Falken
9

Chciałem zauważyć , że chociaż ta odpowiedź działa świetnie w starszych wersjach, psuje się w ostatnich wersjach Apache 2.4 z kodem błędu AH00526. ProxyPassi ProxyPassMatchlub <Proxy>i <ProxyMatch>nie mogą być używane razem w ramach tego samego nazwiska pracownika. Kiedyś działało dobrze, więc nie wiem, czy zostało to zmienione projektowo, czy jest to błąd.

Tak czy inaczej, możesz to naprawić tylko przy użyciu ProxyPassMatch z parametrem „timeout = 120” (lub dowolną pożądaną wartością), np .:

ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/path/to/webroot/$1 timeout=120
Stewart Adam
źródło
6

Mam Apache 2.4.6, ale łatka do naprawy jest dostępna w Apache> = 2.4.8. Kluczem tutaj jest natychmiastowe uruchomienie danych wyjściowych, aby Apache (mod_proxy_fcgi) uznał, że połączenie jest aktywne.

Na przykład używam PHP, a zapytanie DB dla mojego wywołania AJAX zajmuje> 30 sekund. Ponieważ wiem, że ogólną odpowiedzią będzie „Content-Type: application / json”, natychmiast przesyłam ten nagłówek.

#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
źródło
2

Czy nie powinno to być:

<IfModule mod_proxy.c>

Upewnij się, że ustawienie php.ini max_execution_time jest również ustawione na 600. (sprawdź phpinfo () na stronie na żywo, aby upewnić się, że widzisz rzeczywistą zastosowaną wartość)

Jak powiedziała Jenny, ustaw ustawienie php-fpm

request_terminate_timeout 610s

(zwróć uwagę na s)

Jak widać na stronie apache, niewiele można skonfigurować za pomocą samego mod_proxy_fcgi. http://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html

Włącz rejestrowanie debugowania php-fpm, abyś mógł zobaczyć, gdzie się tam kończy. http://php-fpm.org/wiki/Configuration_File (również włącz catch_workers_output)

I włącz rejestrowanie na poziomie debugowania dla modułów mod_proxy i mod_proxy_fcgi, ponieważ używasz Apache 2.4. Bardzo fajna funkcja, włącz tylko te moduły, których potrzebujesz: http://httpd.apache.org/docs/current/mod/core.html#loglevel

Jeśli to nie pomoże, opublikuj plik konfiguracyjny php-fpm.

W ostateczności może jakiś demon zabija długotrwały proces?

troseman
źródło
2

Zauważyłem, że używasz PHP-FPM. Ja też go używam, ale z Apache 2.4.6.

Zakładając, że problem istnieje od jakiegoś czasu, wydaje się, że wartość limitu czasu dla mod_proxy_fcgijest zakodowana na stałe . Zapisałem to, co tu znalazłem

misterich
źródło
1

Ponieważ naprawiłeś ustawienia limitu czasu w Apache, nie powinno to stanowić problemu. Drugim miejscem do obejrzenia jest każdy sprzęt sieciowy, ale ponieważ jesteś proxy do własnego serwera, jest to również mało prawdopodobne. Pozostałym miejscem do obejrzenia jest serwer zaplecza.

Ih plik konfiguracyjny dla php-pfm, poszukaj

; 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

Powinno to być ustawione tak samo lub nieco poniżej limitu czasu w Apache.

Jenny D mówi Przywróć Monikę
źródło
1
Ustawiłem request_terminate_timeoutna 400, wciąż bez zmian :( Mam wrażenie, że jest coś, co muszę ustawić mod_proxy_fcgi, ale nie wydaje się, aby pochodziło z żadnymi plikami konfiguracyjnymi.
wyqydsyq 18.04.2013
0

Oprócz limitu czasu ustaw enablereuse = off. Przekonałem się, że w przypadku niektórych żądań długo działające skrypty działałyby poprawnie, a inne zostały zabite wcześnie.

Ctlq
źródło
0

Ten post zmienił dla mnie całą ofertę.

Wygląda na to, że mod_reqtimeout Apache nie użyłby wartości domyślnej.

Dodaj następujące wiersze do pliku httpd.conf :

<IfModule reqtimeout_module>
  RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
Frosty Z
źródło