Articles

Nginx 502 Bad Gateway: PHP-FPM

tip / nginx / 502 bad gateway/php

Opmerking van de redactie: php-fpm gebruikt de term “master” om zijn primaire proces te beschrijven. Datadog gebruikt deze term niet. Binnen deze blogpost, zullen we verwijzen naar dit als “primaire,” behalve voor de duidelijkheid in gevallen waarin we moeten verwijzen naar een specifieke procesnaam.

dit bericht maakt deel uit van een serie over het oplossen van NGINX 502 slechte Gateway fouten. Als je geen PHP-FPM gebruikt, bekijk dan ons andere artikel over het oplossen van problemen met Nginx 502s met Gunicorn als backend.

PHP-FastCGI Process Manager (PHP-FPM) is een daemon voor het verwerken van webserveraanvragen voor PHP-toepassingen. In productie wordt PHP-FPM vaak ingezet achter een Nginx webserver. NGINX proxies web verzoeken en geeft ze door aan PHP-FPM worker processen die de PHP applicatie uit te voeren.

een diagram toont de stroom van verzoeken van de browser naar Nginx naar PHP-FPM en terug.

NGINX retourneert een 502 slechte Gateway-fout als het een verzoek niet succesvol kan proxy naar PHP-FPM, of als PHP-FPM niet reageert. In dit bericht, we zullen een aantal veel voorkomende oorzaken van 502 fouten in de Nginx/PHP-FPM stack te onderzoeken, en we zullen begeleiding over waar u informatie kunt vinden die u kan helpen deze fouten op te lossen.

ontdek de metrics, logs en sporen achter Nginx 502 slechte Gateway fouten met behulp van Datadog.

enkele mogelijke oorzaken van 502s

In deze sectie beschrijven we hoe de volgende voorwaarden ervoor kunnen zorgen dat NGINX een 502-fout retourneert:

  • PHP-FPM draait niet
  • NGINX kan niet communiceren met PHP-FPM
  • PHP-FPM is timing out

als nginx is niet in staat om te communiceren met php-fpm om een van deze redenen, het zal reageren met een 502 fout, noteert dit in zijn access log (/var/log/Nginx/access.log) zoals getoond in dit voorbeeld:

toegang.log

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

NGINX ‘ s toegangslog verklaart de oorzaak van een 502-fout niet, maar u kunt het foutlogboek (/var/log/nginx/error) raadplegen.log) voor meer informatie. Bijvoorbeeld, hier is een overeenkomstige vermelding in de Nginx error log die laat zien dat de oorzaak van de 502 fout is dat de socket niet bestaat, mogelijk omdat PHP-FPM niet draait. (In de volgende sectie, zullen we kijken naar hoe dit probleem op te sporen en te corrigeren.)

fout.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 draait niet

Opmerking: Deze sectie bevat een procesnaam die de term ” master gebruikt.”Behalve wanneer het gaat om specifieke processen, gebruikt dit artikel in plaats daarvan de term “primair”.

als PHP-FPM niet draait, geeft NGINX een 502-fout terug voor elke aanvraag die bedoeld is om de PHP-applicatie te bereiken. Als je 502s ziet, controleer dan eerst of PHP-FPM draait. Bijvoorbeeld, op een Linux host, kunt u een ps commando zoals deze gebruiken om te zoeken naar het uitvoeren van PHP-FPM processen:

Copy
sudo ps aux | grep 'php'

PHP-FPM organiseert zijn werkprocessen in groepen genaamd pools. De voorbeeld uitvoer hieronder laat zien dat het PHP-FPM primaire proces draait, net als twee werkprocessen in de standaard pool (genaamd www):

kopieer
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

als de uitvoer van de opdracht psgeen PHP-FPM primaire of pool processen toont, moet u PHP-FPM draaiend krijgen om de 502 fouten op te lossen.

in een productieomgeving zou je moeten overwegen systemd te gebruiken om PHP-FPM als service uit te voeren. Dit kan uw PHP applicatie betrouwbaarder en schaalbaar te maken, omdat de PHP-FPM daemon zal automatisch beginnen met het bedienen van uw PHP app wanneer uw server start of wanneer een nieuwe instantie start. PHP-FPM is opgenomen in de PHP broncode, dus je kunt PHP-FPM toevoegen als een systemd service wanneer je PHP configureert.

zodra uw PHP-FPM project is geconfigureerd als een service, kunt u het volgende commando gebruiken om ervoor te zorgen dat het automatisch start wanneer uw server opstart:

kopieer
sudo systemctl enable php7.2-fpm.service

dan kunt u de list-unit-files commando om informatie over uw service te zien:

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

op een PHP 7.2 server waarop PHP-FPM is geïnstalleerd (zelfs als het niet draait), zal de uitvoer van dit commando zijn:

kopiëren
php7.2-fpm.service enabled

om informatie over uw PHP-FPM service te zien, gebruik dan dit commando:

kopiëren
sudo systemctl is-active php7.2-fpm.service

dit commando moet een uitvoer van teruggeven. Als dat niet het geval is, kunt u de service starten met:

kopieer
sudo service php7.2-fpm start

NGINX heeft geen toegang tot de socket

wanneer PHP-FPM start, maakt het een of meer TCP-of Unix-sockets om te communiceren met de Nginx-webserver. PHP-FPM ‘ s werkprocessen gebruiken deze sockets om te luisteren naar verzoeken van NGINX.

om te bepalen of een 502-fout werd veroorzaakt door een verkeerde socket configuratie, moet u bevestigen dat PHP-FPM en NGINX zijn geconfigureerd om dezelfde socket te gebruiken. PHP-FPM gebruikt een apart configuratiebestand voor elke worker process pool; deze bestanden bevinden zich in /etc/php/7.2/fpm/pool.d/. De socket van elke pool wordt gedefinieerd in een listen instructie in het configuratiebestand van de pool. Bijvoorbeeld, de listen instructie hieronder configureert een pool met de naam mypool om een Unix socket te gebruiken Op /run/php/mypool.sock:

mypool.conf

kopieer
listen = /run/php/mypool.sock

als NGINX geen toegang heeft tot de socket voor een bepaalde pool, kunt u bepalen welke werkpool betrokken is bij het probleem door te controleren welke socket een naam heeft in het Nginx-foutlogboek. Als PHP-FPM bijvoorbeeld niet was geslaagd om de mypool worker pool te starten, zou NGINX een 502 retourneren en de fout log vermelding zou bevatten:

fout.log

kopieer
connect() to unix:/run/php/mypool.sock failed (2: No such file or directory)

Controleer uw nginx.conf-bestand om ervoor te zorgen dat het relevante location blok dezelfde socket specificeert. Het voorbeeld hieronder bevat eeninclude richtlijn die wat algemene configuratie informatie voor PHP-FPM laadt, en eenfastcgi_pass richtlijn die dezelfde UNIX socket specificeert die in de mypool wordt genoemd.conf file, hierboven.

nginx.conf

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

Unix-sockets zijn onderworpen aan UNIX-bestandssysteem-rechten. Het configuratiebestand van de PHP-FPM pool specificeert de modus en eigendom van de socket, zoals hier getoond:

www.conf

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

zorg ervoor dat deze rechten de gebruiker en groep die NGINX uitvoert toegang geven tot de socket. Als de rechten op de socket onjuist zijn, zal NGINX een 502-fout in zijn access log registreren, en een bericht zoals hieronder in zijn error log:

fout.log

kopiëren
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"

merk op dat de standaardwaarden van listen.owneren listen.group overeenkomen met de standaardeigenaar en groep die NGINX draait, en listen.mode staat standaard op 0660. Met deze standaardinstellingen zou NGINX toegang moeten hebben tot de socket.

als PHP-FPM luistert op een TCP-socket, zal de poolconifguratie listen een waarde hebben in de vorm van address:port, zoals hieronder getoond:

www.conf

Copy
listen = 127.0.0.1:9000

net als bij een Unix-socket kunt u 502 fouten voorkomen door te bevestigen dat de locatie van deze socket overeenkomt met de locatie die is opgegeven in de Nginx-configuratie.

PHP-FPM timetout

als uw toepassing te lang duurt om te reageren, zullen uw gebruikers een time-outfout ervaren. Als de time-out van PHP-FPM—die is ingesteld in de poolconfiguratie request_terminate_timeout directive (en standaard 20 seconden) – minder is dan de time-out van NGINX (standaard 60 seconden), zal NGINX reageren met een 502-fout. De NGINX error log hieronder geeft aan dat zijn upstream proces—dat is PHP-FPM—sloot de verbinding voordat het verzenden van een geldig antwoord. Met andere woorden, Dit is de error log die we zien wanneer PHP-FPM time out:

fout.log

kopieer
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"

In dit geval, de PHP-FPM log (die standaard staat op/var /log/php7.2-fpm.log) toont een gecorreleerd bericht dat nadere informatie verschaft:

php7. 2-fpm.log

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

U kunt de timeout-instelling van PHP-FPM verhogen door het configuratiebestand van de pool te bewerken, maar dit kan een ander probleem veroorzaken: NGINX kan een time-out krijgen voordat een antwoord van PHP-FPM wordt ontvangen. De standaard Nginx time-out is 60 seconden; als je je PHP-FPM timeout boven 60 seconden hebt verhoogd, zal NGINX een 504 Gateway Timeout fout retourneren als je PHP applicatie niet op tijd heeft gereageerd. U kunt dit voorkomen door ook het verhogen van uw Nginx time-out. In het voorbeeld hieronder hebben we de timeout waarde verhoogd naar 90 seconden door het fastcgi_read_timeout item toe te voegen aan het http blok van /etc/nginx/nginx.conf:

nginx.conf

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

uw Nginx-configuratie herladen om deze wijziging toe te passen:

kopieer
nginx -s reload

vervolgens kunt u logs en application performance monitoring (APM) gegevens verzamelen die de oorzaken van latentie binnen en buiten uw toepassing kunnen onthullen.

verzamel en analyseer uw logs

om toepassingsfouten op te lossen, kunt u uw logs verzamelen en verzenden naar een logbeheerservice. In aanvulling op de Nginx logs we hierboven onderzocht, PHP kan fouten en andere gebeurtenissen die waardevol kunnen zijn voor u loggen. Zie onze PHP logging guide voor meer informatie.

wanneer u uw PHP-en NGINX-logboeken in een logbeheerservice brengt, gecombineerd met logs van relevante technologieën zoals cachingservers en databases, kunt u logs van uw hele webstack analyseren op één platform.

een staafdiagram in Datadog Log Analytics visualiseert PHP en NGINX logs van verschillende statussen zoals fout, waarschuwing en info.
Datadog ‘ s Log Analytics toont logboeken van meerdere services, gegroepeerd op status.

Verzamel APM-gegevens van uw webstack

APM kan u helpen knelpunten te identificeren en problemen op te lossen, zoals 502 fouten, die de prestaties van uw app beïnvloeden. De screenshot hieronder toont Nginx ‘ s APM-gegevens gevisualiseerd in Datadog. Deze weergave vat het aanvraagvolume, de foutenpercentages en de latency samen voor een op NGINX gebaseerde dienst en helpt u prestatieproblemen zoals 502 fouten te onderzoeken.

een weergave van een Nginx-dienst in Datadog APM bevat staafgrafieken die het volume van aanvragen en fouten weergeven, een histogram dat latentiedistributie toont, en een lijngrafiek die latentiewaarden in de tijd toont.

200 OK

hoe sneller u de 502 fouten van uw toepassing kunt diagnosticeren en oplossen, hoe beter. Met Datadog kunt u statistieken, sporen, logboeken en netwerkprestaties analyseren vanuit uw hele infrastructuur. Als u al een Datadog-klant bent, kunt u beginnen met het monitoren van NGINX, PHP-FPM en meer dan400 andere technologieën. Als je nog geen Datadog-account hebt, meld je dan aan voor een gratis proefperiode van 14 dagen en begin binnen enkele minuten.