web-dev-qa-db-fra.com

PHP et mod_fcgid: ap_pass_brigade a échoué dans la fonction handle_request_ipc

Cela a été demandé et répondu avant https://stackoverflow.com/a/12686252/219116 mais, la solution là-bas ne fonctionne pas pour moi.

config mod_fcgid

<IfModule mod_fcgid.c>
  AddHandler    fcgid-script .fcgi
  FcgidIPCDir /var/run/mod_fcgid/
  FcgidProcessTableFile /var/run/mod_fcgid/fcgid_shm

  FcgidIdleTimeout 60
  FcgidProcessLifeTime 120
  FcgidMaxRequestsPerProcess 500
  FcgidMaxProcesses 150
  FcgidMaxProcessesPerClass 144
  FcgidMinProcessesPerClass 0
  FcgidConnectTimeout 30
  FcgidIOTimeout 600
  FcgidIdleScanInterval 10
  FcgidMaxRequestLen 269484032

</IfModule>

script php-cgi

#!/bin/bassh
export PHPRC=/var/www/vhosts/example.com/etc/
export PHP_FCGI_MAX_REQUESTS=5000
exec /usr/bin/php-cgi

Détails du système

  • CentOS Linux version 7.1.1503 (Core)
  • httpd-2.4.6-31.el7.centos.x86_64
  • mod_fcgid-2.3.9-4.el7.x86_64
  • php56u-cli-5.6.12-1.ius.centos7.x86_64

Ainsi, mon FcgidMaxRequestsPerProcess est défini sur 500 et mon PHP_FCGI_MAX_REQUESTS est défini sur 10x, comme suggéré dans les réponses précédentes et la documentation Apache. Et pourtant, je reçois toujours ces erreurs

[Thu Nov 19 18:16:48.197238 2015] [fcgid:warn] [pid 6468:tid 139726677858048]
(32)Broken pipe: [client X.X.X.X:41098] mod_fcgid: ap_pass_brigade failed in handle_request_ipc function
17
Slashterix

L'avertissement n'a rien à voir avec les options Fcgidxxx et est simplement provoqué par la fermeture par le client de son côté de la connexion avant que le serveur n'ait la chance de répondre.

De la source réelle:

/* Now pass any remaining response body data to output filters */
if ((rv = ap_pass_brigade(r->output_filters, brigade_stdout)) != APR_SUCCESS) {
    if (!APR_STATUS_IS_ECONNABORTED(rv)) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                      "mod_fcgid: ap_pass_brigade failed in "
                      "handle_request_ipc function");
    }

    return HTTP_INTERNAL_SERVER_ERROR;
}

Le mérite revient à Avian's Blog qui l'a découvert.

5
aefxx

J'obtiens également le même problème il y a environ un an, alors j'ai essayé beaucoup de choses et, enfin, j'ai fait quelques-unes des choses hit and run après avoir lu la documentation et mon problème a disparu. Tout d'abord, les choses importantes doivent être définies comme:

FcgidBusyTimeout     300 [default]
FcgidBusyScanInterval    120 [default]

Le but de cette directive est de terminer les applications bloquées. Le délai d'expiration par défaut peut devoir être augmenté pour les applications qui peuvent prendre plus de temps pour traiter la demande. Étant donné que la vérification est effectuée à l'intervalle défini par FcgidBusyScanInterval, le traitement des demandes peut être autorisé à se poursuivre pendant une période plus longue

FcgidProcessLifeTime     3600 [default]

Les processus d'application inactifs qui existent depuis plus longtemps que ce temps seront arrêtés si le nombre de processus pour la classe dépasse FcgidMinProcessesPerClass.

Cette vérification de la durée de vie du processus est effectuée à la fréquence du FcgidIdleScanInterval configuré.

FcgidZombieScanInterval   3 [seconds default]

Le module recherche les applications FastCGI fermées à cet intervalle. Pendant cette période, l'application peut exister dans la table de processus en tant que zombie (sous Unix).

Remarque: toutes les options ci-dessus diminuent ou augmentent en fonction du temps ou des besoins de votre processus de candidature ou s'appliquent à un vhost spécifique.

Mais mon problème se résout par cette option:

Les options ci-dessus ont modifié mon serveur mais après un certain temps, les erreurs semblent à nouveau se produire, mais l'erreur est vraiment résolue par ceci:

 FcgidOutputBufferSize   65536 [default]

Je l'ai changé en

 FcgidOutputBufferSize   0

Il s'agit de la quantité maximale de données de réponse que le module lira à partir de l'application FastCGI avant de vider les données vers le client. Cela éliminera instantanément les données sans attendre 64 Ko d'octets, ce qui m'aide vraiment à éliminer le processus plus rapidement.

Autres problèmes que j'ai rencontrés

si 500 Erreur provenant du délai d'expiration de Nginx. La solution:

/etc/nginx/nginx.conf

keepalive_timeout  125;
proxy_read_timeout 125;
proxy_connect_timeout 125;
fastcgi_read_timeout 125;

Par intermittence, j'obtiendrais l'erreur MySQL "Le serveur MySQL est parti", ce qui nécessitait encore un Tweak: /etc/my.conf

wait_timeout = 120

Ensuite, juste pour le fun, j'ai continué et augmenté ma limite de mémoire PHP, juste au cas où: /etc/php.ini

memory_limit = 256M

Utiliser SuExec

mod_fastcgi ne fonctionne pas du tout sous SuExec sur Apache 2.x. Je n'ai eu que des ennuis (il y avait aussi de nombreux autres problèmes dans nos tests). La véritable cause de votre problème est SuExec

Dans mon cas, c'était une startup pour moi, je démarre Apache, mod_fcgid génère exactement 5 processus pour chaque vhost. Maintenant, lorsque vous utilisez un simple script de téléchargement et que vous soumettez un fichier de plus de 4 à 8 Ko, tous ces processus enfants sont tués en même temps pour le vhost spécifique sur lequel le script a été exécuté.

Il pourrait être possible de créer une version de débogage ou de lancer la journalisation dans mod_fcgid, ce qui pourrait donner un indice.

J'ai essayé mod_fastcgi en attendant pendant 1 an et je peux aussi dire avec beaucoup d'autres que SuExec n'est rien d'autre que gênant et ne fonctionne pas du tout en douceur, dans tous les cas.

15
Vineet1982