Articles

Nginx 502 Dålig Gateway: PHP-FPM

tips / nginx / 502 dålig gateway / php

Redaktörens anmärkning: php-fpm använder termen ”master” för att beskriva sin primära process. Datadog använder inte denna term. Inom detta blogginlägg kommer vi att hänvisa till detta som ”primärt”, förutom för tydlighetens skull i fall där vi måste referera till ett specifikt processnamn.

det här inlägget är en del av en serie om felsökning av Nginx 502 dåliga Gateway-fel. Om du inte använder PHP-FPM, kolla in vår andra artikel om felsökning av NGINX 502s med Gunicorn som backend.

PHP-FastCGI Process Manager (PHP-FPM) är en demon för hantering av webbserverförfrågningar för PHP-applikationer. I produktion distribueras PHP-FPM ofta bakom en Nginx webbserver. NGINX proxies webbförfrågningar och skickar dem vidare till PHP-FPM-arbetsprocesser som kör PHP-applikationen.

ett diagram visar flödet av förfrågningar från webbläsaren till NGINX till PHP-FPM och tillbaka.

NGINX returnerar ett 502 dåligt Gateway-fel om det inte lyckas proxy en begäran till PHP-FPM, eller om PHP-FPM inte svarar. I det här inlägget undersöker vi några vanliga orsaker till 502-fel i Nginx/PHP-FPM-stacken, och vi ger vägledning om var du kan hitta information som kan hjälpa dig att lösa dessa fel.

utforska mätvärden, loggar och spår bakom Nginx 502 dåliga Gateway-fel med Datadog.

några möjliga orsaker till 502s

i det här avsnittet beskriver vi hur följande villkor kan få NGINX att returnera ett 502-fel:

  • PHP-FPM körs inte
  • nginx kan inte kommunicera med PHP-FPM
  • PHP-FPM timingar ut

om NGINX inte kan för att kommunicera med php-fpm av någon av dessa skäl kommer den att svara med ett 502-fel och notera detta i sin åtkomstlogg (/var/log/nginx/access.log) som visas i detta exempel:

access.log

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

nginxs åtkomstlogg förklarar inte orsaken till ett 502-fel, men du kan konsultera felloggen (/var/log/nginx / error.log) för att lära dig mer. Här är till exempel en motsvarande post i nginx-felloggen som visar att orsaken till 502-felet är att uttaget inte existerar, möjligen för att PHP-FPM inte körs. (I nästa avsnitt tittar vi på hur du upptäcker och åtgärdar detta problem.)

fel.log

kopiera
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 körs inte

Obs: Det här avsnittet innehåller ett processnamn som använder termen ”master.”Förutom när man hänvisar till specifika processer använder den här artikeln termen ”primär” istället.

om PHP-FPM inte körs returnerar NGINX ett 502-fel för varje begäran som är avsedd att nå PHP-applikationen. Om du ser 502s, kontrollera först att PHP-FPM körs. På en Linux-värd kan du till exempel använda ett ps kommando som det här för att leta efter att köra PHP – FPM-processer:

sudo ps aux | grep 'php'

PHP-FPM organiserar sina arbetsprocesser i grupper kallas pooler. Provutmatningen nedan visar att PHP – FPM-primärprocessen körs, liksom två arbetsprocesser i standardpoolen (heter www):

kopiera
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

om kommandotps inte visar några primära eller poolprocesser i PHP-FPM måste du köra PHP-FPM för att lösa 502-felen.

i en produktionsmiljö bör du överväga att använda systemd för att köra PHP-FPM som en tjänst. Detta kan göra din PHP-applikation mer tillförlitlig och skalbar, eftersom PHP-FPM-demonen automatiskt börjar betjäna din PHP-app när servern startar eller när en ny instans startas. PHP-FPM ingår i PHP-källkoden, så du kan lägga till PHP-FPM som en systemd-tjänst när du konfigurerar PHP.

När ditt PHP-FPM-projekt har konfigurerats som en tjänst kan du använda följande kommando för att säkerställa att det startar automatiskt när servern startar:

sudo systemctl enable php7.2-fpm.service

då kan du användalist-unit-files kommando för att se information om din tjänst:

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

på en PHP 7.2 server som har PHP-FPM installerad (även om den inte körs) kommer utmatningen av detta kommando att vara:

php7.2-fpm.service enabled

För att se information om din PHP-FPM-tjänst, använd det här kommandot:

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

detta kommando ska returnera en utgång på active. Om det inte gör det kan du starta tjänsten med:

kopiera
sudo service php7.2-fpm start

NGINX kan inte komma åt uttaget

När PHP-FPM startar skapar det ett eller flera TCP-eller Unix-uttag för att kommunicera med Nginx webbserver. PHP-FPM: s arbetsprocesser använder dessa uttag för att lyssna på förfrågningar från NGINX.

för att avgöra om ett 502-fel orsakades av en socket-felkonfiguration, bekräfta att PHP-FPM och NGINX är konfigurerade att använda samma socket. PHP-FPM använder en separat konfigurationsfil för varje arbetsprocesspool; dessa filer finns på /etc/php/7.2/fpm/pool.g/. Varje pools uttag definieras i ettlisten – direktiv i poolens konfigurationsfil. Till exempel konfigurerarlisten direktivet nedan en pool med namnetmypool för att använda ett Unix-uttag på /run/php/mypool.socka:

mypool.Conf

kopiera
listen = /run/php/mypool.sock

om NGINX inte kan komma åt uttaget för en viss pool, kan du avgöra vilken arbetarpool som är involverad i problemet genom att kontrollera vilket uttag som heter i nginx felloggposten. Till exempel, om PHP-FPM hade misslyckats med att starta mypool arbetarpool, skulle nginx returnera en 502 och dess felloggpost skulle innehålla:

fel.logga

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

kontrollera din nginx.conf-fil för att säkerställa att det relevanta location – blocket anger samma uttag. Exemplet nedan innehåller ett include – direktiv som laddar viss allmän konfigurationsinformation för PHP-FPM och ettfastcgi_pass – direktiv som anger samma Unix-uttag som heter i mypool.conf-fil, ovan.

nginx.Conf

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

Unix-uttag är föremål för Unix-filsystembehörigheter. PHP-FPM-poolens konfigurationsfil anger läget och ägandet av uttaget, som visas här:

www.Conf

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

se till att dessa behörigheter tillåter användaren och gruppen som kör NGINX att komma åt uttaget. Om behörigheterna på uttaget är felaktiga loggar NGINX ett 502-fel i åtkomstloggen och ett meddelande som det som visas nedan i felloggen:

fel.log

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

Observera att standardvärdena för listen.ownerochlisten.groupmatchar standardägaren och grupp som kör nginx ochlisten.modeStandardvärdet är 0660. Med hjälp av dessa standardvärden bör NGINX kunna komma åt uttaget.

om PHP-FPM lyssnar på ett TCP-uttag kommer pool conifguration ’ slisten direktivet att ha ett värde i form avaddress:port, som visas nedan:

www.conf

kopiera
listen = 127.0.0.1:9000

precis som med ett Unix-uttag kan du förhindra 502 fel genom att bekräfta att platsen för detta uttag matchar den som anges i Nginx-konfigurationen.

PHP-FPM är timing ut

om din ansökan tar för lång tid att svara, kommer användarna att uppleva en timeout fel. Om PHP-FPM: s timeout—som är inställd i poolkonfigurationens request_terminate_timeout—direktiv (och standardvärdet är 20 sekunder) – är mindre än nginx timeout (som Standardvärdet är 60 sekunder), svarar NGINX med ett 502-fel. Nginx-felloggen som visas nedan indikerar att dess uppströmsprocess—som är PHP-FPM—stängde anslutningen innan du skickade ett giltigt svar. Med andra ord är detta felloggen vi ser när PHP-FPM Time out:

fel.log

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

i detta fall är PHP-FPM-loggen (som som standard finns på /var/log/php7.2-fpm.log) visar ett korrelerat meddelande som ger ytterligare information:

php7.2-fpm.log

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

Du kan höja PHP-FPM: s timeout-inställning genom att redigera poolens konfigurationsfil, men det kan orsaka ett annat problem: NGINX kan timeout innan du får ett svar från PHP-FPM. Standard timeout för NGINX är 60 sekunder; om du har höjt din PHP-FPM timeout över 60 sekunder returnerar NGINX ett 504 Gateway Timeout-fel om din PHP-applikation inte har svarat i tid. Du kan förhindra detta genom att också höja din nginx timeout. I exemplet nedan har vi höjt timeout-värdet till 90 sekunder genom att lägga till fastcgi_read_timeout – objektet till http block av /etc/nginx/nginx.conf:

nginx.Conf

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

ladda om din nginx-konfiguration för att tillämpa denna ändring:

kopiera
nginx -s reload

därefter kan du samla loggar och APM-data (application performance monitoring) som kan avslöja orsaker till latens inom och utanför din ansökan.

samla in och analysera dina loggar

för att felsöka programfel kan du samla in dina loggar och skicka dem till en logghanteringstjänst. Förutom nginx-loggarna som vi undersökte ovan kan PHP logga fel och andra händelser som kan vara värdefulla för dig. Se vår PHP loggning guide för mer information.

När du tar med dina PHP-och NGINX-loggar till en logghanteringstjänst, kombinerat med loggar från relevant teknik som cachningsservrar och databaser, kan du analysera loggar från hela din webbstack på en enda plattform.

en stapeldiagram i Datadog Log Analytics visualiserar PHP och NGINX loggar med olika status som fel, varning och info.
Datadogs logganalys visar loggar från flera tjänster, grupperade efter status.

samla APM-data från din webbstack

APM kan hjälpa dig att identifiera flaskhalsar och lösa problem, som 502 fel, som påverkar appens prestanda. Skärmdumpen nedan visar nginx APM-data visualiserad i Datadog. Den här vyn sammanfattar begärningsvolym, felfrekvenser och latens för en nginx-baserad tjänst och hjälper dig att undersöka prestandaproblem som 502 fel.

en vy av en nginx-tjänst i Datadog APM innehåller stapeldiagram som visar volymen av förfrågningar och fel, ett histogram som visar latensfördelning och en raddiagram som visar latensvärden över tiden.

200 OK

ju snabbare du kan diagnostisera och lösa programmets 502 fel, desto bättre. Datadog låter dig analysera mätvärden, spår, loggar och nätverksprestandadata från hela din Infrastruktur. Om du redan är Datadog-kund kan du börja övervaka NGINX, PHP-FPM och mer än 400 andra tekniker. Om du ännu inte har ett Datadog-konto kan du registrera dig för en 14-dagars gratis provperiod och komma igång på några minuter.