Tempo limite do proxy Apache2

23

Eu tenho o Apache2 com PHP + PHP-FPM configurado de acordo com:

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

Estou escrevendo um script que levará muito tempo para ser executado em um Vhost interno, mas continuando com o tempo limite esgotado, tudo será executado sem falhas se o script for executado em menos de 30 segundos.

Meu log do apache me diz:

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

Ao tentar executar o script, recebo um tempo 503 Service Unavailableapós exatamente 30 segundos de execução. Logicamente, isso significaria que eu tenho uma diretiva de tempo limite ou configuração definida como 30 segundos, mas eu as tenho na configuração do meu 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 está sendo executado na porta 9001 para mim)

Eu também tentei colocar o Timeoute ProxyTimeoutdentro httpd.confsem diferença.

Parece que há outro tempo limite definido em algum lugar específico mod_proxy_fcgi, mas não consigo encontrá-lo. Eu instalei o Apache2 httpd do tarball oficial, nenhum dos mods parece ter vindo com nenhum arquivo de configuração.

Se alguém puder me apontar na direção certa, seria muito apreciado.

wyqydsyq
fonte

Respostas:

32

Finalmente resolvi esse problema depois de testar vários parâmetros de configuração. Testei a solução duas vezes, removendo todas as alterações anteriores. Apenas um parâmetro foi necessário para eu corrigi-lo.

Para as versões mais recentes do httpd e mod_proxy_fcgi, você pode simplesmente adicionar timeout=ao final da ProxyPassMatchlinha, por exemplo:

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

Para versões mais antigas, era um pouco mais complicado, por exemplo:

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

Eu precisava adicionar a diretiva Proxy para definir o tempo limite para 30 minutos. Em alguns aplicativos, geralmente ao operar o banco de dados, existem rotinas que podem levar mais de 10 minutos para serem executadas. Temporariamente, defino o tempo limite para 30 minutos para garantir que eles terminem. Especificamente útil ao usar o assistente de instalação, que leva muito tempo (na minha humilde opinião).

A propósito, a entrada inicial que me ajudou a resolver esse problema foi encontrada no seguinte endereço URL .

Jordi Ferran
fonte
1
Parece que este quebrou em versões recentes do Apache, AH00526: ProxyPass / <Proxy> e ProxyPassMatch / <ProxyMatch> não pode ser usado em conjunto com o mesmo nome do trabalhador
Stewart Adam
4
Resolvi o problema acima adicionando um parâmetro 'timeout = 120' no final da linha ProxyPassMatch.
Stewart Adam
@Palantir feliz em ouvi-lo! Enviado como resposta .
Stewart Adam
Mais duas coisas que eu precisava: Primeiro, você deve definir "Timeout" e "ProxyTimeout" no seu arquivo de configuração global do apache para serem maiores que os outros tempos limite do FPM. Segundo, meu pool de FPM estava escutando em um soquete unix e eu uso o SetHandler da seguinte forma: [SetHandler "proxy: unix: /var/run/php/example.com-php7.0-fpm.sock | fcgi: // localhost: 8000 "]. Mas <Proxy> corresponde na parte fcgi: // localhost da linha SetHandler (a parte APÓS o | ... que nem é realmente usada!) E NÃO o unix: / var / run / part. assim o tempo limite de configuração para uso acima: <Proxy fcgi: // localhost: 8000> e não <unix Proxy: / var / run / ...
Professor Falken
9

Queria ressaltar que, embora essa resposta funcione bem para versões mais antigas, ela é quebrada nas versões recentes do Apache 2.4 com o código de erro AH00526. ProxyPasse ProxyPassMatchou <Proxy>e <ProxyMatch>não podem ser usados ​​juntos com o mesmo nome do trabalhador. Isso costumava funcionar muito bem, então não sei se isso foi alterado por design ou se é um bug.

De qualquer forma, você pode corrigir isso usando apenas um ProxyPassMatch com o parâmetro 'timeout = 120' (ou qualquer que seja o valor desejado), por exemplo:

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

Eu tenho o Apache 2.4.6, mas o patch para corrigi-lo é fornecido no Apache> = 2.4.8. A chave aqui é iniciar sua saída imediatamente, para que o Apache (mod_proxy_fcgi) pense que a conexão está ativa.

Por exemplo, estou usando PHP e a consulta ao banco de dados para minha chamada AJAX leva> 30 segundos. Como sei que a resposta geral será "Content-Type: application / json", envio esse cabeçalho imediatamente.

#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
fonte
2

Não deveria ser:

<IfModule mod_proxy.c>

Certifique-se de que a configuração max_execution_time do php.ini também esteja definida como 600. (verifique phpinfo () na página ao vivo para garantir que você esteja vendo o valor real usado)

Como Jenny disse, defina a configuração php-fpm

request_terminate_timeout 610s

(observe os s no final)

Não há muito o que configurar com o próprio mod_proxy_fcgi, como você pode ver na página apache. http://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html

Ative o log de depuração do php-fpm também para que você possa ver o tempo limite por aí. http://php-fpm.org/wiki/Configuration_File (também ative catch_workers_output)

E ative o log de nível de depuração para os módulos mod_proxy e mod_proxy_fcgi desde que você esteja usando o apache 2.4. Recurso muito bom, ative apenas para os módulos necessários: http://httpd.apache.org/docs/current/mod/core.html#loglevel

Se isso não ajudar, poste seu arquivo de configuração php-fpm.

Como último recurso, talvez algum daemon esteja matando um longo processo de execução?

troseman
fonte
2

Notei que você está usando PHP-FPM. Eu também uso, mas com o Apache 2.4.6.

Supondo que o problema existe há algum tempo, parece que o valor do tempo limite mod_proxy_fcgié codificado . Eu escrevi o que encontrei aqui

misterich
fonte
1

Como você corrigiu as configurações de tempo limite no apache, esse não deve ser o problema. O segundo lugar para procurar seria qualquer equipamento de rede, mas como você faz proxy para seu próprio servidor, isso também é improvável. Portanto, o lugar restante para procurar é no servidor back-end.

No arquivo de configuração do php-pfm, procure

; 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

Isso deve ser definido como o mesmo ou um pouco abaixo da configuração de tempo limite no apache.

Jenny D diz Restabelecer Monica
fonte
1
Eu configurei a request_terminate_timeout400, ainda nenhuma mudança :( Eu tenho a sensação de que há algo que eu preciso definir para mod_proxy_fcgi, mas não parecem vir com quaisquer arquivos de configuração.
wyqydsyq
0

Além do tempo limite, defina enablereuse = off. Descobri que quando estava em alguns pedidos de scripts de longa execução funcionaria corretamente e outros seriam mortos mais cedo.

ctlq
fonte
0

Este post mudou todo o negócio para mim.

Parece que o mod_reqtimeout do Apache não usaria o valor padrão.

Adicione as seguintes linhas ao seu arquivo httpd.conf :

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