Articles

NGINX 502 Mauvaise passerelle: PHP-FPM

tip/nginx/502 mauvaise passerelle/php

Note de l’éditeur: php-fpm utilise le terme « maître” pour décrire son processus principal. Datadog n’utilise pas ce terme. Dans cet article de blog, nous appellerons cela « primaire”, sauf par souci de clarté dans les cas où nous devons faire référence à un nom de processus spécifique.

Cet article fait partie d’une série sur le dépannage des erreurs de passerelle NGINX 502. Si vous n’utilisez pas PHP-FPM, consultez notre autre article sur le dépannage de NGINX 502 avec Gunicorn comme backend.

PHP-FastCGI Process Manager (PHP-FPM) est un démon pour gérer les requêtes de serveur web pour les applications PHP. En production, PHP-FPM est souvent déployé derrière un serveur web NGINX. NGINX proxie les requêtes Web et les transmet aux processus de travail PHP-FPM qui exécutent l’application PHP.

Un diagramme montre le flux des requêtes du navigateur vers NGINX vers PHP-FPM et inversement.

NGINX renverra une erreur de passerelle 502 Bad s’il ne parvient pas à proxy une requête à PHP-FPM, ou si PHP-FPM ne répond pas. Dans cet article, nous examinerons certaines causes courantes des erreurs 502 dans la pile NGINX / PHP-FPM, et nous vous indiquerons où vous pouvez trouver des informations pouvant vous aider à résoudre ces erreurs.

Explorez les métriques, les journaux et les traces derrière les erreurs de passerelle NGINX 502 à l’aide de Datadog.

Quelques causes possibles de 502s

Dans cette section, nous allons décrire comment les conditions suivantes peuvent amener NGINX à renvoyer une erreur 502:

  • PHP-FPM ne fonctionne pas
  • NGINX ne peut pas communiquer avec PHP-FPM
  • PHP-FPM est en retard

Si NGINX est incapable de communiquer avec PHP-FPM pour l’une de ces raisons, il répondra avec une erreur 502, en notant cela dans son journal d’accès (/var/log/nginx/access.log) comme indiqué dans cet exemple :

accès.log

Copy
127.0.0.1 - - "GET / HTTP/1.1" 502 182 "-" "curl/7.58.0"

Le journal d’accès de NGINX n’explique pas la cause d’une erreur 502, mais vous pouvez consulter son journal d’erreurs (/var/log/nginx/error.log) pour en savoir plus. Par exemple, voici une entrée correspondante dans le journal des erreurs NGINX qui montre que la cause de l’erreur 502 est que le socket n’existe pas, peut-être parce que PHP-FPM n’est pas en cours d’exécution. (Dans la section suivante, nous verrons comment détecter et corriger ce problème.)

erreur.log

Copy
2020/01/31 18:30:55 13617#13617: *557 connect() to unix:/run/php/php7.2-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.2-fpm.sock:", host: "localhost"

PHP-FPM ne fonctionne pas

Remarque: Cette section inclut un nom de processus qui utilise le terme « master. »Sauf lorsqu’il s’agit de processus spécifiques, cet article utilise le terme « primaire” à la place.

Si PHP-FPM n’est pas en cours d’exécution, NGINX renverra une erreur 502 pour toute requête destinée à atteindre l’application PHP. Si vous voyez 502s, vérifiez d’abord que PHP-FPM est en cours d’exécution. Par exemple, sur un hôte Linux, vous pouvez utiliser une commande ps comme celle-ci pour rechercher des processus PHP-FPM en cours d’exécution :

Copy
sudo ps aux | grep 'php'

PHP-FPM organise ses processus de travail en groupes appelés piscines. L’exemple de sortie ci-dessous montre que le processus primaire PHP-FPM est en cours d’exécution, tout comme deux processus de travail dans le pool par défaut (nommé www):

Copy
root 29852 0.0 2.2 435484 22396 ? Ssl 16:27 0:00 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf)www-data 29873 0.0 1.5 438112 15220 ? Sl 16:27 0:00 php-fpm: pool wwwwww-data 29874 0.0 1.6 438112 16976 ? Sl 16:27 0:00 php-fpm: pool www

Si la sortie de la commande ps n’affiche aucun processus primaire ou pool PHP-FPM, vous devrez exécuter PHP-FPM pour résoudre les 502 erreurs.

Dans un environnement de production, vous devriez envisager d’utiliser systemd pour exécuter PHP-FPM en tant que service. Cela peut rendre votre application PHP plus fiable et évolutive, car le démon PHP-FPM commencera automatiquement à servir votre application PHP au démarrage de votre serveur ou au lancement d’une nouvelle instance. PHP-FPM est inclus dans le code source de PHP, vous pouvez donc ajouter PHP-FPM en tant que service systemd lorsque vous configurez PHP.

Une fois que votre projet PHP-FPM est configuré en tant que service, vous pouvez utiliser la commande suivante pour vous assurer qu’il démarre automatiquement au démarrage de votre serveur :

Copy
sudo systemctl enable php7.2-fpm.service

Ensuite, vous pouvez utiliser le list-unit-files pour voir les informations sur votre service :

Copiez
sudo systemctl list-unit-files | grep -E 'php*fpm'

Sur un PHP 7.2 serveur sur lequel PHP-FPM est installé (même s’il n’est pas en cours d’exécution), la sortie de cette commande sera :

Copy
php7.2-fpm.service enabled

Pour voir des informations sur votre service PHP-FPM, utilisez cette commande :

Copy

/div>

sudo systemctl is-active php7.2-fpm.service

Cette commande doit renvoyer une sortie de active. Si ce n’est pas le cas, vous pouvez démarrer le service avec:

Copy
sudo service php7.2-fpm start

NGINX ne peut pas accéder au socket

Lorsque PHP-FPM démarre, il crée un ou plusieurs sockets TCP ou Unix pour communiquer avec le serveur Web NGINX. Les processus de travail de PHP-FPM utilisent ces sockets pour écouter les requêtes de NGINX.

Pour déterminer si une erreur 502 a été causée par une mauvaise configuration du socket, confirmez que PHP-FPM et NGINX sont configurés pour utiliser le même socket. PHP-FPM utilise un fichier de configuration distinct pour chaque pool de processus de travail ; ces fichiers se trouvent dans /etc/php/7.2/fpm/pool.d/. Le socket de chaque pool est défini dans une directive listen dans le fichier de configuration du pool. Par exemple, la directive listen ci-dessous configure un pool nommé mypool pour utiliser un socket Unix situé dans /run/php/mypool.chaussette :

mypool.conf

Copy
listen = /run/php/mypool.sock

Si NGINX ne peut pas accéder au socket pour un pool particulier, vous pouvez déterminer quel pool de travail est impliqué dans le problème en vérifiant quel socket est nommé dans l’entrée du journal des erreurs NGINX. Par exemple, si PHP-FPM n’avait pas réussi à démarrer le pool de travailleurs mypool, NGINX retournerait un 502 et son entrée de journal d’erreurs inclurait :

erreur.si vous avez besoin d’une copie de votre fichier nginx, vous pouvez vérifier votre nginx.fichier conf pour s’assurer que le bloc location approprié spécifie le même socket. L’exemple ci-dessous contient une directive include qui charge des informations de configuration générales pour PHP-FPM, et une directive fastcgi_pass qui spécifie le même socket Unix nommé dans le mypool.fichier conf, ci-dessus.

nginx.conf

Copy
location / { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/mypool.sock;}

Les sockets Unix sont soumises aux autorisations du système de fichiers Unix. Le fichier de configuration du pool PHP-FPM spécifie le mode et la propriété du socket, comme indiqué ici :

www.conf

Copiez
listen.owner = www-datalisten.group = www-datalisten.mode = 0660

Assurez-vous que ces autorisations permettent à l’utilisateur et au groupe exécutant NGINX d’accéder au socket. Si les autorisations sur le socket sont incorrectes, NGINX enregistrera une erreur 502 dans son journal d’accès et un message comme celui indiqué ci-dessous dans son journal d’erreurs :

erreur.log

Copy
2020/02/20 17:12:03 3059#3059: *4 connect() to unix:/run/php/mypool.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/mypool.sock:", host: "localhost"

Notez que les valeurs par défaut de listen.owner et listen.group correspondent au propriétaire par défaut et groupe exécutant NGINX, et listen.mode par défaut à 0660. En utilisant ces valeurs par défaut, NGINX devrait pouvoir accéder au socket.

Si PHP-FPM écoute sur un socket TCP, la directive listen de la conifguration du pool aura une valeur sous la forme de address:port, comme indiqué ci-dessous :

www.conf

Copy
listen = 127.0.0.1:9000

Tout comme avec un socket Unix, vous pouvez éviter 502 erreurs en confirmant que l’emplacement de ce socket correspond à celui spécifié dans la configuration NGINX.

PHP-FPM expire

Si votre application met trop de temps à répondre, vos utilisateurs connaîtront une erreur de délai d’attente. Si le délai d’attente de PHP-FPM — qui est défini dans la directive request_terminate_timeout de la configuration du pool (et est par défaut de 20 secondes) – est inférieur au délai d’attente de NGINX (qui est par défaut de 60 secondes), NGINX répondra avec une erreur 502. Le journal des erreurs NGINX ci—dessous indique que son processus en amont – qui est PHP—FPM – a fermé la connexion avant d’envoyer une réponse valide. En d’autres termes, c’est le journal des erreurs que nous voyons lorsque PHP-FPM expire:

erreur.log

Copiez
2020/02/20 17:17:12 3059#3059: *29 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/mypool.sock:", host: "localhost"

Dans ce cas, le journal PHP-FPM (qui se trouve par défaut dans /var/log/php7.2-fpm.log) affiche un message corrélé qui fournit des informations supplémentaires :

php7.2-fpm.log

Copy
 WARNING: child 2120, script '/var/www/html/index.php' (request: "GET /index.php") execution timed out (25.755070 sec), terminating

Vous pouvez déclencher le paramètre timeout de PHP-FPM en modifiant le fichier de configuration du pool, mais cela pourrait causer un autre problème: NGINX peut expirer avant de recevoir une réponse de PHP-FPM. Le délai d’expiration NGINX par défaut est de 60 secondes; si vous avez augmenté votre délai d’expiration PHP-FPM au-dessus de 60 secondes, NGINX renverra une erreur de délai d’expiration de la passerelle 504 si votre application PHP n’a pas répondu à temps. Vous pouvez empêcher cela en augmentant également votre délai d’expiration NGINX. Dans l’exemple ci-dessous, nous avons augmenté la valeur de délai d’attente à 90 secondes en ajoutant l’élément fastcgi_read_timeout au bloc http de /etc/nginx/nginx.conf:

nginx.conf

Copiez
http { ... fastcgi_buffers 8 16k; fastcgi_buffer_size 32k; fastcgi_connect_timeout 90; fastcgi_send_timeout 90; fastcgi_read_timeout 90;}

Rechargez votre configuration NGINX pour appliquer cette modification:

Copy
nginx -s reload

Ensuite, pour déterminer pourquoi PHP-FPM a expiré, vous pouvez collecter des journaux et des données de surveillance des performances des applications (APM) qui peuvent révéler des causes de latence à l’intérieur et à l’extérieur de votre application.

Collectez et analysez vos journaux

Pour résoudre les erreurs d’application, vous pouvez collecter vos journaux et les envoyer à un service de gestion des journaux. En plus des journaux NGINX que nous avons examinés ci-dessus, PHP peut enregistrer des erreurs et d’autres événements qui pourraient vous être utiles. Consultez notre guide de journalisation PHP pour plus d’informations.

Lorsque vous intégrez vos journaux PHP et NGINX dans un service de gestion des journaux, combinés à des journaux provenant de technologies pertinentes telles que les serveurs de mise en cache et les bases de données, vous pouvez analyser les journaux de l’ensemble de votre pile Web sur une seule plate-forme.

Un graphique à barres dans Datadog Log Analytics visualise les journaux PHP et NGINX de différents statuts tels que les erreurs, les avertissements et les informations.
L’analyse des journaux de Datadog affiche les journaux de plusieurs services, regroupés par statut.

Collectez les données APM de votre pile Web

APM peut vous aider à identifier les goulots d’étranglement et à résoudre les problèmes, tels que les erreurs 502, qui affectent les performances de votre application. La capture d’écran ci-dessous montre les données APM de NGINX visualisées dans Datadog. Cette vue résume le volume des demandes, les taux d’erreur et la latence pour un service basé sur NGINX et vous aide à étudier les problèmes de performances tels que les erreurs 502.

Une vue d'un service NGINX dans Datadog APM comprend des graphiques à barres montrant le volume de requêtes et d'erreurs, un histogramme montrant la distribution de la latence et un graphique linéaire montrant les valeurs de latence au fil du temps.

200 OK

Plus vite vous pouvez diagnostiquer et résoudre les 502 erreurs de votre application, mieux c’est. Datadog vous permet d’analyser les métriques, les traces, les journaux et les données de performance réseau de l’ensemble de votre infrastructure. Si vous êtes déjà client de Datadog, vous pouvez commencer à surveiller NGINX, PHP-FPM et plus de 400 autres technologies. Si vous n’avez pas encore de compte Datadog, inscrivez-vous pour un essai gratuit de 14 jours et commencez en quelques minutes.