NGINX 502 Bad Gateway: PHP-FPM
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.
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
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
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:
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
):
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:
sudo systemctl enable php7.2-fpm.service
atunci puteți utilizalist-unit-files
comanda pentru a vedea informații despre serviciul dvs.:
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:
php7.2-fpm.service enabled
pentru a vedea informații despre serviciul PHP-FPM, utilizați această comandă:
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:
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
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
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 relevantlocation
specifică același soclu. Exemplul de mai jos conține o directivăinclude
care încarcă unele informații generale de configurare pentru PHP-FPM și o directivăfastcgi_pass
care specifică același soclu Unix numit în mypool.fișier conf, de mai sus.
nginx.conf
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
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
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.group
se potrivesc cu proprietarul implicit și grupul care rulează nginx șilisten.mode
implicit 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
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
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
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
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:
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ă.
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.
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.
Leave a Reply