J'ai Apache2 avec PHP + PHP-FPM configuré selon:
http://wiki.Apache.org/httpd/PHP-FPM
J'écris un script qui prendra beaucoup de temps à exécuter sur un Vhost interne, mais continuez à expirer, tout fonctionne parfaitement si le script s'exécute en moins de 30 secondes.
Mon journal Apache me dit:
[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:
Lorsque j'essaie d'exécuter le script, je reçois un 503 Service Unavailable
après exactement 30 secondes de temps d'exécution. Logiquement, cela signifierait que j'ai une directive de délai d'attente ou un paramètre défini sur 30 secondes, mais je les ai dans la configuration de mon 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 fonctionne sur le port 9001 pour moi)
J'ai également essayé de placer les Timeout
et ProxyTimeout
dans httpd.conf
sans différence.
Il semble qu'il y ait un autre paramètre de délai d'attente quelque part spécifique à mod_proxy_fcgi
, mais je ne le trouve pas. J'ai installé Apache2 httpd à partir de l'archive tar officielle, aucun des mods ne semble être venu avec des fichiers de configuration.
Si quelqu'un peut m'orienter dans la bonne direction, ce serait très apprécié.
J'ai finalement résolu ce problème après avoir testé plusieurs paramètres de configuration. J'ai testé la solution deux fois, supprimant toutes les modifications précédentes. Un seul paramètre était nécessaire pour que je puisse le réparer.
Pour les dernières versions de httpd et mod_proxy_fcgi, vous pouvez simplement ajouter timeout=
jusqu'à la fin de la ligne ProxyPassMatch
, par exemple:
ProxyPassMatch ^/(.+\.php.*)$ fcgi://127.0.0.1:9000/<docroot>/$1 timeout=1800
Pour les anciennes versions, c'était un peu plus compliqué, par exemple:
<Proxy fcgi://127.0.0.1:9000>
ProxySet timeout=1800
</Proxy>
ProxyPassMatch ^/(.+\.php.*)$ fcgi://127.0.0.1:9000/<docroot>/$1
J'ai dû ajouter la directive Proxy pour définir le délai d'expiration à 30 minutes. Dans certaines applications, généralement lors de l'utilisation de la base de données, il existe des routines dont l'exécution peut prendre plus de 10 minutes. J'ai temporairement fixé le délai à 30 minutes pour m'assurer qu'ils se terminent. Particulièrement utile lors de l'utilisation de l'assistant d'installation, ce qui prend trop de temps (à mon humble avis).
Au fait, l'entrée initiale qui m'a aidé à résoudre ce problème a été trouvée dans ce qui suit adresse URL .
Je voulais souligner que bien que cette réponse fonctionne très bien pour les anciennes versions, il casse sous les versions récentes d'Apache 2.4 avec le code d'erreur AH00526. ProxyPass
et ProxyPassMatch
ou <Proxy>
et <ProxyMatch>
ne peut pas être utilisé ensemble sous le même nom de travailleur. Cela fonctionnait très bien, donc je ne sais pas si cela a été modifié par conception ou s'il s'agit d'un bogue.
Dans les deux cas, vous pouvez résoudre ce problème en utilisant uniquement un ProxyPassMatch avec le paramètre 'timeout = 120' (ou quelle que soit la valeur souhaitée), par exemple:
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/path/to/webroot/$1 timeout=120
J'ai Apache 2.4.6, mais le patch pour le corriger est fourni dans Apache> = 2.4.8. La clé ici est de démarrer votre sortie immédiatement afin qu'Apache (mod_proxy_fcgi) pense que la connexion est active.
Par exemple, j'utilise PHP et la requête DB pour mon AJAX appel prend> 30 secondes. Parce que je sais que la réponse globale sera "Content- Type: application/json ", j'envoie cet en-tête immédiatement.
#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
Cela ne devrait-il pas être:
<IfModule mod_proxy.c>
Assurez-vous que le paramètre php.ini max_execution_time est également défini sur 600. (vérifiez phpinfo () sur la page en direct pour vous assurer que vous voyez la valeur réelle utilisée)
Comme l'a dit Jenny, définissez le paramètre php-fpm
request_terminate_timeout 610s
(notez les s à la fin)
Il n'y a pas grand-chose à configurer avec mod_proxy_fcgi lui-même, comme vous pouvez le voir sur la page Apache. http://httpd.Apache.org/docs/current/mod/mod_proxy_fcgi.html
Activez également la journalisation du débogage php-fpm afin que vous puissiez voir où cela arrive. http://php-fpm.org/wiki/Configuration_File (activez également catch_workers_output)
Et activez la journalisation du niveau de débogage pour les modules mod_proxy et mod_proxy_fcgi puisque vous utilisez Apache 2.4. Très belle fonctionnalité, activez uniquement les modules dont vous avez besoin: http://httpd.Apache.org/docs/current/mod/core.html#loglevel
Si cela ne vous aide pas, postez votre fichier de configuration php-fpm.
En dernier recours, peut-être qu'un démon tue un long processus?
J'ai remarqué que vous utilisez PHP-FPM. Moi aussi je l'utilise, mais avec Apache 2.4.6.
En supposant que le problème existe depuis un certain temps, il semble que la valeur de délai d'attente pour mod_proxy_fcgi
est codé en dur. J'ai écrit ce que j'ai trouvé ici
Puisque vous avez corrigé les paramètres de délai d'attente dans Apache, cela ne devrait pas être le problème. Le deuxième endroit à rechercher serait tout équipement réseau, mais comme vous êtes mandataire sur votre propre serveur, cela est également peu probable. L'endroit restant à regarder est donc le serveur principal.
Ih le fichier de configuration pour php-pfm, recherchez
; 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
Ce paramètre doit être identique ou légèrement inférieur au paramètre de délai d'expiration dans Apache.
Cet article a changé toute l'affaire pour moi.
Il semble que mod_reqtimeout d'Apache n'utilise pas la valeur par défaut.
Ajoutez les lignes suivantes à votre fichier httpd.conf :
<IfModule reqtimeout_module>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
En plus du délai d'expiration, définissez enablereuse = off. J'ai trouvé que lorsque c'était sur certaines demandes, des scripts de longue durée fonctionneraient correctement et d'autres seraient tués tôt.