Articles

NGINX 502 Bad Gateway: PHP – FPM

tip / nginx /502 bad gateway /php

Nota del redattore: php-fpm usa il termine “master” per descrivere il suo processo primario. Datadog non usa questo termine. All’interno di questo post del blog, ci riferiremo a questo come “primario”, tranne che per motivi di chiarezza nei casi in cui dobbiamo fare riferimento a un nome di processo specifico.

Questo post fa parte di una serie sulla risoluzione dei problemi NGINX 502 Bad Gateway errors. Se non stai usando PHP-FPM, controlla il nostro altro articolo sulla risoluzione dei problemi NGINX 502s con Gunicorn come backend.

PHP-FastCGI Process Manager (PHP-FPM) è un demone per la gestione delle richieste del server web per le applicazioni PHP. In produzione, PHP-FPM è spesso distribuito dietro un server web NGINX. NGINX procura le richieste web e le trasmette ai processi di lavoro PHP-FPM che eseguono l’applicazione PHP.

Un diagramma mostra il flusso di richieste dal browser a NGINX a PHP-FPM e viceversa.

NGINX restituirà un errore di 502 Bad Gateway se non riesce a proxy correttamente una richiesta a PHP-FPM, o se PHP-FPM non risponde. In questo post, esamineremo alcune cause comuni di errori 502 nello stack NGINX / PHP-FPM e forniremo indicazioni su dove è possibile trovare informazioni che possono aiutare a risolvere questi errori.

Esplora le metriche, i log e le tracce dietro gli errori di NGINX 502 Bad Gateway utilizzando Datadog.

Alcune possibili cause di 502s

In questa sezione descriveremo come le seguenti condizioni possono causare NGINX per restituire un errore 502:

  • PHP-FPM non è in esecuzione
  • NGINX non può comunicare con PHP-FPM
  • PHP-FPM timeout

Se NGINX è in grado di comunicare con PHP-FPM per una di queste ragioni, risponderà con un errore 502, notando ciò, a sua access log (/var/log/nginx/accesso.log) come mostrato in questo esempio:

access.log

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

Il log di accesso di NGINX non spiega la causa di un errore 502, ma puoi consultare il suo log degli errori (/var/log/nginx / error.log) per saperne di più. Ad esempio, ecco una voce corrispondente nel log degli errori NGINX che mostra che la causa dell’errore 502 è che il socket non esiste, probabilmente perché PHP-FPM non è in esecuzione. (Nella prossima sezione, vedremo come rilevare e correggere questo problema.)

errore.log

Copia
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 non è in esecuzione

Nota: Questa sezione include un nome di processo che utilizza il termine “master.”Tranne quando si fa riferimento a processi specifici, questo articolo utilizza invece il termine “primario”.

Se PHP-FPM non è in esecuzione, NGINX restituirà un errore 502 per qualsiasi richiesta destinata a raggiungere l’applicazione PHP. Se stai vedendo 502s, prima controlla per confermare che PHP-FPM è in esecuzione. Ad esempio, su un host Linux, è possibile utilizzare un comando ps come questo per cercare l’esecuzione di processi PHP-FPM:

Copy
sudo ps aux | grep 'php'

PHP-FPM organizza i suoi processi di lavoro in gruppi chiamato piscine. L’output di esempio seguente mostra che il processo primario PHP-FPM è in esecuzione, così come due processi di lavoro nel pool predefinito (denominato www):

Copia
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

Se l’output del comando ps non mostra alcun processo primario o pool di PHP-FPM, è necessario far funzionare PHP-FPM per risolvere gli errori 502.

In un ambiente di produzione, dovresti considerare l’utilizzo di systemd per eseguire PHP-FPM come servizio. Ciò può rendere la tua applicazione PHP più affidabile e scalabile, poiché il demone PHP-FPM inizierà automaticamente a servire la tua app PHP all’avvio del tuo server o all’avvio di una nuova istanza. PHP-FPM è incluso nel codice sorgente PHP, quindi puoi aggiungere PHP-FPM come servizio systemd quando configuri PHP.

una Volta che il vostro PHP-FPM progetto si configura come un servizio, è possibile utilizzare il comando seguente per assicurarsi che si avvia automaticamente quando il server si avvia:

Copia
sudo systemctl enable php7.2-fpm.service

Poi si può usare il tag list-unit-files comando per visualizzare le informazioni relative al vostro servizio:

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

un PHP 7.2 server PHP-FPM installato (anche se non è in esecuzione), l’output di questo comando:

Copia
php7.2-fpm.service enabled

Per informazioni su PHP-FPM servizio, utilizzare questo comando:

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

Questo comando dovrebbe restituire un output di active. In caso contrario, è possibile avviare il servizio con:

Copy
sudo service php7.2-fpm start

NGINX non può accedere al socket

All’avvio di PHP-FPM, crea uno o più socket TCP o Unix per comunicare con il server web NGINX. I processi di lavoro di PHP-FPM usano questi socket per ascoltare le richieste da NGINX.

Per determinare se un errore 502 è stato causato da un’errata configurazione del socket, verificare che PHP-FPM e NGINX siano configurati per utilizzare lo stesso socket. PHP-FPM utilizza un file di configurazione separato per ogni pool di processi di lavoro; questi file si trovano in /etc/php/7.2/fpm/pool.d/. Il socket di ogni pool è definito in una direttivalisten nel file di configurazione del pool. Ad esempio, la direttivalisten di seguito configura un pool denominatomypool per utilizzare un socket Unix situato in /run/php/mypool.calzino:

mypool.conf

Copy
listen = /run/php/mypool.sock

Se NGINX non può accedere al socket per un particolare pool, è possibile determinare quale pool di lavoratori è coinvolto nel problema controllando quale socket è denominato nella voce del log degli errori NGINX. Ad esempio, se PHP-FPM non fosse riuscito ad avviare il pool di lavoratori mypool, NGINX restituirebbe un 502 e la sua voce di registro degli errori includerebbe:

errore.log

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

Controlla il tuo nginx.file conf per garantire che il relativo bloccolocation specifichi lo stesso socket. L’esempio seguente contiene una direttivainclude che carica alcune informazioni generali di configurazione per PHP-FPM e una direttivafastcgi_pass che specifica lo stesso socket Unix denominato in mypool.file conf, sopra.

nginx.conf

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

I socket Unix sono soggetti alle autorizzazioni del file system Unix. Il file di configurazione del pool PHP-FPM specifica la modalità e la proprietà del socket, come mostrato qui:

www.conf

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

Assicurati che queste autorizzazioni consentano all’utente e al gruppo che esegue NGINX di accedere al socket. Se le autorizzazioni sul socket non sono corrette, NGINX registrerà un errore 502 nel suo log di accesso e un messaggio come quello mostrato di seguito nel suo log degli errori:

errore.log

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

si noti che i valori di default listen.owner e listen.group match il proprietario predefinito e di gruppo, in esecuzione di NGINX, e listen.mode default 0660. Usando questi valori predefiniti, NGINX dovrebbe essere in grado di accedere al socket.

Se PHP-FPM è in ascolto su un socket TCP, la direttivalisten del pool di conifguration avrà un valore sotto forma diaddress:port, come mostrato di seguito:

www.conf

Copia
listen = 127.0.0.1:9000

Proprio come con un socket Unix, è possibile prevenire 502 errori confermando che la posizione di questo socket corrisponde a quella specificata nella configurazione NGINX.

PHP-FPM sta scadendo

Se l’applicazione richiede troppo tempo per rispondere, gli utenti riscontreranno un errore di timeout. Se il timeout di PHP-FPM-che è impostato nella direttiva request_terminate_timeout della configurazione del pool (e il valore predefinito è 20 secondi) – è inferiore al timeout di NGINX (il valore predefinito è 60 secondi), NGINX risponderà con un errore 502. Il log degli errori NGINX mostrato di seguito indica che il suo processo upstream—che è PHP-FPM—ha chiuso la connessione prima di inviare una risposta valida. In altre parole, questo è il log degli errori che vediamo quando PHP-FPM scade:

errore.log

Copia
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 questo caso, il registro PHP-FPM (che per impostazione predefinita si trova in / var / log / php7.2-fpm.log) mostra un messaggio correlato che fornisce ulteriori informazioni:

php7. 2-fpm.log

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

È possibile aumentare l’impostazione di timeout di PHP-FPM modificando il file di configurazione del pool, ma questo potrebbe causare un altro problema: NGINX potrebbe scadere prima di ricevere una risposta da PHP-FPM. Il timeout predefinito di NGINX è di 60 secondi; se hai aumentato il timeout PHP-FPM sopra i 60 secondi, NGINX restituirà un errore di timeout del gateway 504 se l’applicazione PHP non ha risposto in tempo. Puoi prevenirlo aumentando anche il timeout di NGINX. Nell’esempio seguente, abbiamo aumentato il valore di timeout a 90 secondi aggiungendo l’elementofastcgi_read_timeout al bloccohttp di /etc/nginx/nginx.conf:

nginx.conf

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

Ricarica la configurazione NGINX per applicare questa modifica:

Copy
nginx -s reload

Successivamente, per determinare il motivo del timeout di PHP-FPM, è possibile raccogliere i log e i dati APM (Application Performance Monitoring) che possono rivelare le cause di latenza all’interno e all’esterno dell’applicazione.

Raccogliere e analizzare i log

Per risolvere gli errori delle applicazioni, è possibile raccogliere i log e inviarli a un servizio di gestione dei log. Oltre ai log NGINX che abbiamo esaminato sopra, PHP può registrare errori e altri eventi che potrebbero essere preziosi per te. Vedi la nostra guida alla registrazione PHP per ulteriori informazioni.

Quando si mettono i log PHP e NGINX in un servizio di gestione dei log, combinato con i log di tecnologie rilevanti come i server e i database di caching, è possibile analizzare i log di tutto lo stack Web in un’unica piattaforma.

Un grafico a barre in Datadog Log Analytics visualizza i registri PHP e NGINX di diversi stati come errore, avviso e informazioni.
Log Analytics di Datadog mostra i registri da più servizi, raggruppati per stato.

Raccogli i dati APM dal tuo stack web

APM può aiutarti a identificare i colli di bottiglia e risolvere problemi, come 502 errori, che influenzano le prestazioni della tua app. Lo screenshot qui sotto mostra i dati APM di NGINX visualizzati in Datadog. Questa vista riassume il volume delle richieste, i tassi di errore e la latenza per un servizio basato su NGINX e consente di analizzare problemi di prestazioni come gli errori 502.

Una vista di un servizio NGINX in Datadog APM include grafici a barre che mostrano il volume di richieste ed errori, un istogramma che mostra la distribuzione della latenza e un grafico a linee che mostra i valori di latenza nel tempo.

200 OK

Più velocemente è possibile diagnosticare e risolvere i 502 errori dell’applicazione, meglio è. Datadog consente di analizzare metriche, tracce, log e dati sulle prestazioni di rete da tutta l’infrastruttura. Se sei già un cliente Datadog, è possibile avviare il monitoraggio NGINX, PHP-FPM, e più than400 altre tecnologie. Se non hai ancora un account Datadog, registrati per una prova gratuita di 14 giorni e inizia in pochi minuti.