Articles

NGINX 502 Bad Gateway: PHP-FPM

tip / nginx /502 Bad gateway /php

Nota editorului: php-fpm folosește termenul „master” pentru a descrie procesul său principal. Datadog nu utilizează acest termen. În cadrul acestei postări pe blog, ne vom referi la acest lucru ca „primar”, cu excepția clarității în cazurile în care trebuie să facem referire la un anumit nume de proces.

acest post face parte dintr-o serie de depanare NGINX 502 erori Bad Gateway. Dacă nu utilizați PHP-FPM, consultați celălalt articol despre depanarea NGINX 502s cu Gunicorn ca backend.

PHP-FastCGI Process Manager (PHP-FPM) este un demon pentru gestionarea cererilor de server web pentru aplicații PHP. În producție, PHP-FPM este adesea implementat în spatele unui server web NGINX. NGINX proxy-uri cereri web și le transmite la procesele de lucru PHP-FPM care execută aplicația PHP.

o diagramă arată fluxul de solicitări din browser către NGINX către PHP-FPM și înapoi.

NGINX va returna o eroare 502 Bad Gateway dacă nu poate proxy cu succes o solicitare către PHP-FPM sau dacă PHP-FPM nu răspunde. În această postare, vom examina câteva cauze comune ale erorilor 502 din stiva NGINX/PHP-FPM și vom oferi îndrumări despre unde puteți găsi informații care vă pot ajuta să rezolvați aceste erori.

explorați valorile, jurnalele și urmele din spatele erorilor NGINX 502 Bad Gateway folosind Datadog.

unele cauze posibile ale 502s

În această secțiune, vom descrie modul în care următoarele condiții pot determina NGINX să returneze o eroare 502:

  • PHP-FPM nu rulează
  • NGINX nu poate comunica cu PHP-FPM
  • PHP-FPM se sincronizează

dacă NGINX nu pentru a comunica cu PHP-FPM din oricare dintre aceste motive, acesta va răspunde cu o eroare 502, notând acest lucru în jurnalul său de acces (/var/log/nginx/access.log) așa cum se arată în acest exemplu:

acces.jurnal

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

Jurnalul de acces NGINX nu explică cauza unei erori 502, dar puteți consulta jurnalul său de erori (/var/log/nginx / error.jurnal) pentru a afla mai multe. De exemplu, aici este o intrare corespunzătoare în Jurnalul de erori NGINX care arată că cauza erorii 502 este că soclul nu există, posibil pentru că PHP-FPM nu rulează. (În secțiunea următoare, vom analiza cum să detectăm și să corectăm această problemă.)

eroare.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 nu rulează

Notă: Această secțiune include un nume de proces care folosește termenul „master.”Cu excepția cazului în care se referă la procese specifice, Acest articol folosește în schimb termenul „primar”.

dacă PHP-FPM nu rulează, NGINX va returna o eroare 502 pentru orice solicitare menită să ajungă la aplicația PHP. Dacă vedeți 502s, verificați mai întâi pentru a confirma că PHP-FPM rulează. De exemplu, pe o gazdă Linux, puteți utiliza o comandă ps ca aceasta pentru a căuta rularea proceselor PHP-FPM:

Copy
sudo ps aux | grep 'php'

PHP-FPM își organizează procesele de lucru în grupuri numite piscine. Ieșirea eșantionului de mai jos arată că procesul primar PHP-FPM rulează, la fel ca și două procese de lucru din pool-ul implicit (denumit 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

dacă ieșirea comenziips nu afișează niciun proces primar sau pool PHP-FPM, va trebui să rulați PHP-FPM pentru a rezolva erorile 502.

într-un mediu de producție, ar trebui să luați în considerare utilizarea systemd pentru a rula PHP-FPM ca serviciu. Acest lucru vă poate face aplicația PHP mai fiabilă și mai scalabilă, deoarece demonul PHP-FPM va începe automat să vă servească aplicația PHP atunci când serverul dvs. pornește sau când se lansează o nouă instanță. PHP-FPM este inclus în codul sursă PHP, astfel încât să puteți adăuga PHP-FPM ca serviciu systemd atunci când configurați PHP.

odată ce proiectul PHP-FPM este configurat ca un serviciu, puteți utiliza următoarea comandă pentru a vă asigura că pornește automat când serverul dvs. pornește:

Copiere
sudo systemctl enable php7.2-fpm.service

atunci puteți utilizalist-unit-filescomanda pentru a vedea informații despre serviciul dvs.:

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

pe un PHP 7.2 server care are instalat PHP-FPM (chiar dacă nu rulează), ieșirea acestei comenzi va fi:

Copy
php7.2-fpm.service enabled

pentru a vedea informații despre serviciul PHP-FPM, utilizați această comandă:

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

această comandă ar trebui să returneze o ieșire de active. Dacă nu, puteți începe serviciul cu:

Copy
sudo service php7.2-fpm start

NGINX nu poate accesa soclul

când PHP-FPM pornește, creează unul sau mai multe socluri TCP sau Unix pentru a comunica cu serverul web NGINX. Procesele de lucru PHP-FPM folosesc aceste prize pentru a asculta cererile de la NGINX.

pentru a determina dacă o eroare 502 a fost cauzată de o configurare greșită a soclului, confirmați că PHP-FPM și NGINX sunt configurate să utilizeze același soclu. PHP-FPM utilizează un fișier de configurare separat pentru fiecare grup de procese de lucru; aceste fișiere sunt localizate la /etc/php/7.2/fpm/pool.d/. Soclul fiecărui pool este definit într-o directivălisten în fișierul de configurare al pool-ului. De exemplu, Directiva listen de mai jos configurează un pool numit mypool pentru a utiliza un soclu Unix situat la /run/php/mypool.ciorap:

mypool.conf

Copy
listen = /run/php/mypool.sock

dacă NGINX nu poate accesa soclul pentru un anumit pool, puteți determina care grup de lucrători este implicat în problemă verificând care soclu este denumit în intrarea jurnalului de erori NGINX. De exemplu, dacă PHP-FPM nu a reușit să porneascămypool worker pool, NGINX ar returna un 502 și intrarea sa în Jurnalul de erori ar include:

eroare.log

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

verificați nginx-ul.fișier conf pentru a se asigura că blocul relevantlocationspecifică același soclu. Exemplul de mai jos conține o directivăincludecare încarcă unele informații generale de configurare pentru PHP-FPM și o directivăfastcgi_passcare specifică același soclu Unix numit în mypool.fișier conf, de mai sus.

nginx.conf

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

soclurile UNIX sunt supuse permisiunilor sistemului de fișiere Unix. Fișierul de configurare al grupului PHP-FPM specifică modul și proprietatea soclului, așa cum se arată aici:

www.conf

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

asigurați-vă că aceste permisiuni permit utilizatorului și grupului care rulează NGINX să acceseze soclul. Dacă permisiunile de pe soclu sunt incorecte, NGINX va înregistra o eroare 502 în jurnalul său de acces și un mesaj precum cel prezentat mai jos în jurnalul său de erori:

eroare.log

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

rețineți că valorile implicite alelisten.ownerșilisten.groupse potrivesc cu proprietarul implicit și grupul care rulează nginx șilisten.modeimplicit la 0660. Folosind aceste valori implicite, NGINX ar trebui să poată accesa soclul.

dacă PHP-FPM ascultă pe un soclu TCP, Directivalisten va avea o valoare sub formaaddress:port, așa cum se arată mai jos:

www.conf

Copy
listen = 127.0.0.1:9000

la fel ca în cazul unui soclu Unix, puteți preveni erorile 502 confirmând că locația acestui soclu se potrivește cu cea specificată în configurația NGINX.

PHP-FPM este timing out

În cazul în care cererea dumneavoastră este de a lua prea mult timp pentru a răspunde, utilizatorii vor experimenta o eroare de timeout. Dacă timeout-ul PHP-FPM-care este setat în configurația pool—ului request_terminate_timeout directivă (și implicit la 20 de secunde) – este mai mic decât timeout-ul NGINX (care implicit la 60 de secunde), NGINX va răspunde cu o eroare 502. Jurnalul de erori NGINX prezentat mai jos indică faptul că procesul său din amonte—care este PHP-FPM—a închis conexiunea înainte de a trimite un răspuns valid. Cu alte cuvinte, acesta este jurnalul de erori pe care îl vedem când PHP-FPM expiră:

eroare.log

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

în acest caz, Jurnalul PHP-FPM (care implicit este localizat la/var / log / php7.2-FPM.log) afișează un mesaj corelat care oferă informații suplimentare:

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

puteți ridica setarea de expirare PHP-FPM editând fișierul de configurare al pool-ului, dar aceasta ar putea cauza o altă problemă: NGINX poate expira înainte de a primi un răspuns de la PHP-FPM. Timpul de expirare implicit NGINX este de 60 de secunde; dacă ați ridicat timeout-ul PHP-FPM peste 60 de secunde, NGINX va returna o eroare de Timeout 504 Gateway dacă aplicația PHP nu a răspuns la timp. Puteți preveni acest lucru ridicând, de asemenea, timpul de expirare NGINX. În exemplul de mai jos, am ridicat valoarea timeout la 90 de secunde prin adăugarea elementului fastcgi_read_timeout la blocul http din /etc/nginx/nginx.conf:

nginx.conf

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

Reîncărcați configurația NGINX pentru a aplica această modificare:

Copy
nginx -s reload

apoi, pentru a determina de ce PHP-FPM a expirat, puteți colecta jurnale și date de monitorizare a performanței aplicației (APM) care pot dezvălui cauzele latenței în interiorul și în afara aplicației.

colectați și analizați jurnalele

pentru a depana erorile aplicației, puteți colecta jurnalele și le puteți trimite la un serviciu de gestionare a jurnalelor. În plus față de jurnalele NGINX pe care le-am examinat mai sus, PHP poate înregistra erori și alte evenimente care ar putea fi valoroase pentru dvs. Consultați ghidul nostru de logare PHP pentru mai multe informații.

când aduceți jurnalele PHP și NGINX într-un serviciu de gestionare a jurnalelor, combinate cu jurnalele de la tehnologii relevante, cum ar fi serverele de cache și bazele de date, puteți analiza jurnalele din întreaga stivă web într-o singură platformă.

un grafic cu bare din Datadog Log Analytics vizualizează jurnalele PHP și NGINX cu diferite stări, cum ar fi erori, avertismente și informații.
Datadog ‘ s Log Analytics afișează jurnalele de la mai multe servicii, grupate după stare.

colectați date APM din stiva dvs. web

APM vă poate ajuta să identificați blocajele și să rezolvați probleme, cum ar fi erorile 502, care afectează performanța aplicației. Imaginea de mai jos prezintă datele APM ale NGINX vizualizate în Datadog. Această vizualizare rezumă volumul solicitărilor, ratele de eroare și latența pentru un serviciu bazat pe NGINX și vă ajută să investigați probleme de performanță, cum ar fi erorile 502.

o vizualizare a unui serviciu NGINX în Datadog APM include grafice cu bare care arată volumul cererilor și erorilor, o histogramă care arată distribuția latenței și un grafic liniar care arată valorile latenței în timp.

200 OK

cu cât puteți diagnostica și rezolva mai repede Erorile 502 ale aplicației dvs., cu atât mai bine. Datadog vă permite să analizați valorile, urmele, jurnalele și datele de performanță ale rețelei din întreaga infrastructură. Dacă sunteți deja un client Datadog, puteți începe monitorizarea NGINX, PHP-FPM și a altor tehnologii than400. Dacă nu aveți încă un cont Datadog, înscrieți-vă pentru o încercare gratuită de 14 zile și începeți în câteva minute.