Apache2 Proxy timeout

23

Tengo Apache2 con PHP + PHP-FPM configurado de acuerdo con:

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

Estoy escribiendo un script que tardará mucho tiempo en ejecutarse en un Vhost interno, pero se agota el tiempo de espera, todo funciona perfectamente si el script se ejecuta en menos de 30 segundos.

Mi registro de apache me dice:

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

Cuando trato de ejecutar el script, recibo 503 Service Unavailableexactamente 30 segundos de tiempo de ejecución. Lógicamente, esto significaría que tengo una directiva de tiempo de espera o configuración establecida en 30 segundos, pero tengo estos en la configuración de mi 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 se está ejecutando en el puerto 9001 para mí)

También he intentado colocar el Timeouty ProxyTimeouten httpd.confsin diferencias.

Parece que hay otra configuración de tiempo de espera en algún lugar que es específica mod_proxy_fcgi, pero no puedo encontrarla. Instalé el httpd de Apache2 desde el tarball oficial, ninguno de los mods parece haber venido con ningún archivo de configuración.

Si alguien puede señalarme en la dirección correcta, sería muy apreciado.

wyqydsyq
fuente

Respuestas:

32

Finalmente solucioné este problema después de probar varios parámetros de configuración. Probé la solución dos veces, eliminando todos los cambios anteriores. Solo necesitaba un parámetro para solucionarlo.

Para las últimas versiones de httpd y mod_proxy_fcgi, simplemente puede agregar timeout=al final de la ProxyPassMatchlínea, por ejemplo:

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

Para versiones anteriores era un poco más complicado, por ejemplo:

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

Necesitaba agregar la directiva Proxy para establecer el tiempo de espera en 30 minutos. En algunas aplicaciones, generalmente cuando se opera la base de datos, hay rutinas que pueden demorar más de 10 minutos en ejecutarse. Establecí temporalmente el tiempo de espera en 30 minutos para asegurar que terminen. Específicamente útil cuando se utiliza el asistente de instalación, que lleva demasiado tiempo (en mi humilde opinión).

Por cierto, la entrada inicial que me ayudó a resolver este problema se encontró en la siguiente dirección URL .

Jordi Ferran
fuente
1
Parece que esto se rompió en las versiones recientes de Apache, AH00526: ProxyPass / <Proxy> y ProxyPassMatch / <ProxyMatch> no se pueden usar del todo con el mismo nombre de trabajador
Stewart Adam el
44
He resuelto lo anterior agregando un parámetro 'timeout = 120' al final de la línea ProxyPassMatch.
Stewart Adam
@Palantir contento de escucharlo! Enviado como respuesta .
Stewart Adam
Dos cosas más que necesitaba: Primero, debe -configurar "Tiempo de espera" y "ProxyTimeout" en su archivo de configuración global de apache para que sea más largo que los otros tiempos de espera de FPM. En segundo lugar, mi grupo de FPM estaba escuchando en un socket Unix y uso SetHandler de esta manera: [SetHandler "proxy: unix: /var/run/php/example.com-php7.0-fpm.sock | fcgi: // localhost: 8000 "]. Pero <Proxy> coincide en la parte fcgi: // localhost de la línea SetHandler (la parte DESPUÉS de | ... que ni siquiera se usa realmente) y NO el unix: / var / run / part. para configurar los tiempos de espera para el uso anterior: <Proxy fcgi: // localhost: 8000> y no <Proxy unix: / var / run / ...
Profesor Falken
9

Quería señalar que, aunque esta respuesta funciona muy bien para versiones anteriores, se rompe con las versiones recientes de Apache 2.4 con el código de error AH00526. ProxyPassy ProxyPassMatcho <Proxy>y <ProxyMatch>no se pueden usar juntos dentro del mismo nombre de trabajador. Esto solía funcionar bien, así que no sé si eso fue cambiado por diseño o si es un error.

De cualquier manera, puede solucionar esto utilizando solo un ProxyPassMatch con el parámetro 'timeout = 120' (o cualquiera que sea el valor deseado), por ejemplo:

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

Tengo Apache 2.4.6, pero el parche para solucionarlo se proporciona en Apache> = 2.4.8. La clave aquí es comenzar su salida inmediatamente para que Apache (mod_proxy_fcgi) piense que la conexión está activa.

Por ejemplo, estoy usando PHP y la consulta DB para mi llamada AJAX tarda> 30 segundos. Como sé que la respuesta general será "Tipo de contenido: aplicación / json", envío ese encabezado de inmediato.

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

¿No debería ser eso?

<IfModule mod_proxy.c>

Asegúrese de que la configuración php.ini max_execution_time también esté establecida en 600. (revise phpinfo () en la página en vivo para asegurarse de que está viendo el valor real utilizado)

Como dijo Jenny, establezca la configuración php-fpm

request_terminate_timeout 610s

(tenga en cuenta la s al final)

No hay mucho que configurar con mod_proxy_fcgi, como puede ver en la página de apache. http://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html

Active el registro de depuración php-fpm también para que pueda ver dónde se agota el tiempo. http://php-fpm.org/wiki/Configuration_File (también active catch_workers_output)

Y active el registro de nivel de depuración para los módulos mod_proxy y mod_proxy_fcgi ya que está usando apache 2.4. Muy buena característica, enciéndala solo para los módulos que necesita: http://httpd.apache.org/docs/current/mod/core.html#loglevel

Si eso no ayuda, publique su archivo de configuración php-fpm.

Como último recurso, ¿tal vez algún demonio está matando el proceso de larga ejecución?

troseman
fuente
2

Noté que estás usando PHP-FPM. Yo también lo uso, pero con Apache 2.4.6.

Suponiendo que el problema existe desde hace algún tiempo, parece ser que el valor de tiempo de espera mod_proxy_fcgiestá codificado . Escribí lo que encontré aquí

misterich
fuente
1

Dado que ha arreglado la configuración de tiempo de espera en apache, ese no debería ser el problema. El segundo lugar para buscar sería cualquier equipo de red, pero dado que está utilizando su propio servidor, eso también es poco probable. Por lo tanto, el lugar restante para buscar es el servidor de fondo.

Ih el archivo de configuración para php-pfm, busque

; 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

Esto debe establecerse de la misma manera o un poco por debajo de la configuración de tiempo de espera en apache.

Jenny D dice Reinstate Monica
fuente
1
He configurado el valor request_terminate_timeouta 400, todavía no hay cambios :( Tengo la sensación de que hay algo que necesito configurar mod_proxy_fcgi, pero no parece venir con ningún archivo de configuración.
wyqydsyq
0

Además del tiempo de espera, configure enablereuse = off. Encontré que cuando estaba en algunas solicitudes, los scripts de larga ejecución funcionarían correctamente y otros serían asesinados antes.

ctlq
fuente
0

Esta publicación cambió todo el trato para mí.

Parece que mod_reqtimeout de Apache no estaría usando el valor predeterminado.

Agregue las siguientes líneas a su archivo httpd.conf :

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