Mentre lavoravo sul sito Web del mio cliente basato su WooCommerce, mi è capitato di vedere la pagina di pagamento non riuscita con un messaggio di errore "502 Bad gateway". Sospettavo che il problema potesse essere dovuto a NGINX ed è successo che fosse vero. Il registro degli errori NGINX letto come 'upstream ha inviato un'intestazione troppo grande durante la lettura dell'intestazione della risposta dalla richiesta upstream:GET /checkout/HTTP/1.1, upstream:fastcgi://unix:/var/run/php-fpm/php- fpm.sock '. In questo tutorial, spiegherò in cosa consiste l'errore e come risolverlo.
Cosa significa l'errore "Upstream ha inviato un'intestazione troppo grande durante la lettura intestazione della risposta da upstream” significa?
Capisco che la pagina sembra inviare un'intestazione troppo grande rispetto alla capacità dell'estremità ricevente. Ma qual era la dimensione dell'intestazione troppo grande per essere gestita dal server? Poiché la pagina che ho ricevuto, l'errore era la pagina di pagamento, che includeva 10 articoli aggiunti al carrello. Quindi, i cookie, il contenuto della pagina erano tutti alti e ciò avrebbe potuto comportare una dimensione dell'intestazione maggiore. Quindi, come trovare cosa includono le intestazioni di risposta? È semplice.
- Avvia il browser Chrome, fai clic con il pulsante destro del mouse e seleziona
Inspect
- Fai clic su
Network
scheda - Ricarica la pagina
- Seleziona una delle richieste HTTP dal pannello di sinistra e visualizza le intestazioni HTTP nel pannello di destra.
Va bene, sai per visualizzare le intestazioni HTTP. Ma perché il server ha fallito con un errore "Upstream ha inviato un'intestazione troppo grande durante la lettura dell'intestazione della risposta da upstream"? Bene, la risposta è che ogni server web ha una dimensione massima dell'intestazione impostata e le intestazioni della richiesta HTTP inviate erano troppo grandi di quelle impostate nel server web. Di seguito è riportato il limite massimo della dimensione dell'intestazione su vari server Web.
- Server web Apache – 8K
- NGINX:da 4K a 8K
- IIS (varia in ciascuna versione) – da 8K a 16K
- Tomcat (varia in ogni versione):da 8K a 48K.
Poiché il server Web che sto utilizzando è NGINX, il limite di dimensione dell'intestazione predefinito è compreso tra 4K e 8K. Per impostazione predefinita NGINX utilizza la dimensione della pagina di sistema, che è 4K nella maggior parte dei sistemi. Puoi trovarlo usando il comando seguente:
# getconf PAGESIZE 4096
Ecco uno snippet che spiega le dimensioni del buffer di risposta NGINX FastCGI.
Per impostazione predefinita, quando Nginx inizia a ricevere una risposta da un backend FastCGI (come PHP-FPM), memorizza la risposta nel buffer prima di consegnarla al client. Qualsiasi risposta maggiore della dimensione del buffer impostata viene salvata in un file temporaneo su disco.
I due parametri correlati al buffering della risposta FastCGI sono:
fastcgi_buffers
fastcgi_buffer_size
buffer_fastcgi – controlla il numero e la dimensione della memoria dei segmenti del buffer utilizzati per il carico utile della risposta FastCGI.
fastcgi_buffer_size – controlla la dimensione del buffer utilizzata per contenere il primo blocco di risposta fastCGI dalle intestazioni della risposta HTTP.
Secondo la documentazione di NGNIX, non è necessario regolare il valore predefinito dei parametri di risposta fastCGI, poiché NGINX per impostazione predefinita utilizza la dimensione della pagina più piccola di 4 KB e dovrebbe adattarsi alla maggior parte delle richieste di intestazione HTTP. Tuttavia, non sembra adattarsi al mio caso. La stessa documentazione dice che alcuni dei framework potrebbero inviare grandi quantità di dati sui cookie tramite Set-Cookie
Intestazione HTTP e ciò potrebbe far saltare il buffer con conseguente errore HTTP 500. In questi casi, potrebbe essere necessario aumentare la dimensione del buffer a 8k/16k/32k per ospitare un'intestazione HTTP upstream più grande.
Come trovare le dimensioni medie e massime della risposta FastCGI ricevute dal web server?
Questo può essere scoperto raccogliendo i file di registro degli accessi NGINX. Per farlo, esegui il comando seguente fornendo il access_log
file come input
$ awk '($9 ~ /200/) { i++;sum+=$10;max=$10>max?$10:max; } END { printf("Maximum: %d\nAverage: %d\n",max,i?sum/i:0); }' access.log
Esempio sul mio server web:
Maximum: 3501304 Average: 21065
Nota :la risposta HTTP 200 OK è stata solo presa in considerazione.
Dall'istantanea sopra, è chiaro che la dimensione media del buffer è superiore a 21K. Quindi dobbiamo impostare la dimensione del buffer leggermente superiore alla richiesta media, che probabilmente può essere 32K. Per farlo, apri il file nginx.conf e aggiungi le righe seguenti sotto location
sezione – location ~ \.php$ { }
fastcgi_buffers 32 32k; fastcgi_buffer_size 32k;
Nota :Potrebbe essere necessario impostare un valore del buffer inferiore. Avevo impostato 32K poiché la dimensione media era superiore a 21K.
Ulteriori informazioni sui buffer di risposta FastCGI qui.