503 o 403 istantaneo: guardate prima sopra l'applicazione
Una pagina di errore che arriva senza alcuna latenza è stata servita prima che la vostra applicazione girasse, quindi la checklist parte dall'edge e scende fino al codice per ultimo.
In questo articolo 4 sezioni
- Un errore lento vi dà qualcosa da profilare. Uno istantaneo (un 503, 502, 403 o 429 che arriva in pochi millisecondi) significa che ha risposto un livello sopra l'applicazione, ed è da quel livello che parte la checklist.
- I livelli sopra l'applicazione, dall'alto in basso: CDN e regole di edge, il load balancer e lo stato dei suoi backend, il pannello di controllo o l'interruttore di manutenzione, le regole di rewrite e deny del web server, il DNS, i permessi del filesystem e SELinux.
- Identificate il livello dalla risposta stessa: header del server, forma del body, tempo al primo byte, e la stessa richiesta ripetuta direttamente verso l'origin, aggirando un livello alla volta.
Zero latenza è la prima misura
Il tempo al primo byte vi dice se l'applicazione ha fatto del lavoro. Un errore che arriva all'incirca al tempo di andata e ritorno della rete è stato deciso senza di lei. Un errore generato dall'applicazione porta con sé il tempo che ha speso prima di arrendersi.
curl -s -o /dev/null -w 'code=%{http_code} ttfb=%{time_starttransfer} total=%{time_total}\n' https://site.example/
curl -sI https://site.example/Gli header nominano il livello più spesso che no. Un header Server o Via che appartiene all'edge o al balancer e non al web server, un X-Cache o un request id dell'edge, un body in testo semplice dove l'applicazione renderizzerebbe un template: ognuno dice chi ha risposto. Con questo in mano la checklist è corta.
La checklist, dall'alto in basso
Il CDN o l'edge. Una regola WAF, un rate limit, una regola geografica, una challenge anti-bot, o un problema di certificato tra l'edge e l'origin, che l'edge riporta come un proprio 5xx. Aggiratelo: risolvete il nome direttamente sull'origin e ripetete la richiesta.
curl -s -o /dev/null -w 'code=%{http_code} ttfb=%{time_starttransfer}\n' \
--resolve site.example:443:ORIGIN_IP https://site.example/L'origin risponde 200, l'edge risponde 5xx: l'errore è dell'edge, e lo è anche la regola che l'ha prodotto.
Il load balancer. HAProxy risponde 503 da solo quando nessun backend è up, con il proprio header Server e un body di una riga. È una questione di health check, non di applicazione: un percorso di check cambiato nell'ultimo deploy, una porta di check spostata, o un backend marcato down per una ragione che la pagina delle statistiche mostra. Richiedete un backend direttamente dall'host del balancer per confermare che serve.
Il livello piattaforma. Uno stato di sospensione o di manutenzione nel pannello di controllo, l'interruttore di manutenzione di uno strumento di deploy, un servizio scalato a zero. Ognuno serve una pagina fissa senza invocare l'applicazione, e ognuno è un flag che potete leggere, non una teoria.
Le regole del web server. Una singola direttiva return, rewrite o deny risponde all'istante e sembra catastrofica. Scaricate la configurazione effettiva invece del file che pensate sia caricato.
# nginx: the configuration actually in effect, with the rules that short-circuit a request
nginx -T 2>/dev/null | grep -nE '^\s*(return|rewrite|deny|allow)\b'
# IIS: the URL Rewrite rules for the site
appcmd list config /section:system.webServer/rewrite/rulesSu Apache, leggete la catena effettiva di .htaccess per il percorso, non solo il vhost.
Il DNS. Confermate che il nome risolva all'host su cui state facendo debug. Un record stantio, una differenza split-horizon o una modifica ancora in propagazione significano che la macchina che state guardando non è quella che risponde.
Permessi e SELinux. Il web server non riesce a leggere la document root o a connettersi al socket upstream. Un 403 o un 502 senza alcuna riga nel log dell'applicazione. Su un sistema in enforcing il log di audit nomina il diniego, e la correzione è un modulo di policy, non un cambio di modalità.
ausearch -m avc -ts recent | audit2whySolo ora, l'applicazione. Pool di worker, runtime, dipendenze, il codice. Sono singolarmente costosi da indagare e non possono essere la causa di una risposta che l'applicazione non ha prodotto.
Due dettagli che allungano la caccia
Un 429 ha due possibili autori. Un limiter di edge lo risponde con gli header propri dell'edge e tipicamente un Retry-After; un limiter applicativo lo risponde da dentro l'app, con gli header dell'app e dopo che l'app ha fatto del lavoro. Il tempo al primo byte e gli header li separano, e la correzione sta in un posto diverso per ciascuno.
Una pagina di errore può sopravvivere alla sua causa. Edge e reverse proxy possono mettere in cache un 5xx per breve tempo, così l'origin si riprende e l'edge continua a servire l'errore memorizzato finché non scade. Un header Age sulla risposta di errore dice che è una copia in cache. Fate il purge del percorso sull'edge, o aspettate che il TTL scada, prima di concludere che la correzione non ha funzionato.
Fate sì che ogni livello dimostri se stesso
Ogni passo qui sopra accoppia un livello con un modo per aggirarlo: risolvere direttamente sull'origin aggira l'edge, richiedere un backend dall'host del balancer aggira il balancer, richiedere la porta dell'applicazione su localhost aggira il web server. Il primo salto in cui la risposta cambia dall'errore al contenuto è il livello a cui l'errore appartiene. Il metodo è meccanico di proposito, ed è ciò che lo rende veloce a qualsiasi ora.
Risposte dirette
Cosa causa un 503 istantaneo senza alcun ritardo?+
Qualcosa ha risposto prima che l'applicazione girasse: una regola di edge, un balancer senza backend sani, una pagina di sospensione o manutenzione, una regola di rewrite, un DNS che punta altrove, o un diniego di permessi o SELinux. Zero latenza significa guardare sopra l'applicazione.
Come capisco se l'errore l'ha restituito il CDN o il mio server?+
Leggete gli header Server e Via e il body, poi ripetete la richiesta con curl --resolve puntato all'origin. Se l'origin serve contenuto e l'edge serve l'errore, l'errore è dell'edge.
Perché HAProxy restituisce 503 quando la mia applicazione sta girando?+
Perché il suo health check dice il contrario. Un percorso o una porta di check cambiati, o un backend che fallisce il check per una ragione che la pagina delle statistiche mostra, lasciano il balancer senza alcun server da usare. Correggete il check, non l'applicazione.
Come vedo le regole di rewrite che potrebbero bloccare una richiesta?+
Su nginx, nginx -T stampa la configurazione in vigore; cercatevi con grep return, rewrite, deny e allow. Su IIS, appcmd list config /section:system.webServer/rewrite/rules elenca le regole del sito. Su Apache, leggete la catena di .htaccess per il percorso.
Al prossimo 5xx che non ha senso, partite dalla cima dello stack.
Oppure parlate con un ingegnere che lo fa già.
Parla con un ingegnereSiete arrivati alla fine.
Mettete la lettura al lavoro
Cosa fate girare?
Raccontateci il carico di lavoro, il traffico e i requisiti di ripristino. Partite dal configuratore di server, oppure discutete i dettagli con un ingegnere.
Scritto dagli ingegneri che costruiscono e gestiscono l'infrastruttura che descrive.Parla con un ingegnere
