En 502 Bad Gateway-fejl betyder, at en server, der fungerer som gateway eller proxy, fik et ugyldigt svar fra serveren bag sig. Den besøgende nåede frem til noget, som regel nginx, Apache, en load balancer eller et CDN, men det lag kunne ikke få et ordentligt svar fra din applikation. Applikationen er gået ned, er ved at genstarte, lytter et andet sted eller lukkede forbindelsen halvvejs.
Derfor handler en 502 om to servere, ikke én. Denne guide viser, hvordan du finder ud af, hvilket lag der returnerede den, hvordan du løser de sædvanlige årsager, og hvordan du hører om den næste 502, før dine kunder gør.
Hvad en 502 fortæller dig
De fleste websites har mindst to lag mellem den besøgende og koden. Et CDN eller en load balancer står forrest, en webserver som nginx afslutter forbindelsen, og en applikationsproces, for eksempel PHP-FPM, Node.js, Gunicorn eller en Java-server, bygger siden. Hvert lag sender forespørgslen videre til det næste og sender svaret tilbage.
En 502 opstår, når et af de lag sender en forespørgsel videre og ikke får noget brugbart tilbage. Sammenlign den med de andre gateway-fejl:
502 Bad Gateway: upstream-serveren svarede med noget ugyldigt, nulstillede forbindelsen eller afviste den.
503 Service Unavailable: tjenesten er overbelastet, under vedligeholdelse eller har ingen sund server at sende forespørgslen til.
504 Gateway Timeout: upstream-serveren svarede ikke i tide.
En 502 betyder altså som regel ødelagt eller ikke kørende, en 504 som regel langsom. Vores snydeark over HTTP-statuskoder viser resten af familien, og guiden til 503-fejl dækker overbelastning og vedligeholdelse.
Find det lag, der returnerede 502
Før du ændrer noget, så find ud af, hvem der svarede. Fejlsiden og svarets headers siger det som regel ligeud:
curl -sI https://www.example.com/checkout
HTTP/2 502
server: cloudflare
cf-ray: 8d2f1c3a5b7e4a21-ARN
server: cloudflare med en Cloudflare-fejlside, der nævner din host: Cloudflare nåede din origin, og det var originen, der fejlede.
server: nginx eller Apache med en enkel fejlside: din egen webserver kunne ikke nå applikationen bag sig.
server: awselb/2.0 eller en anden load balancer: load balanceren fik ikke et gyldigt svar fra nogen target eller fra den, den valgte.
Sammenlign derefter med en forespørgsel, der springer det yderste lag over. Send den direkte til originen eller til applikationens port på selve serveren:
curl -sI –resolve www.example.com:443:203.0.113.10 https://www.example.com/checkout
curl -sI http://127.0.0.1:3000/checkout
Hvis applikationen svarer lokalt, men ikke gennem proxyen, så kig på proxyens konfiguration. Hvis den heller ikke svarer lokalt, er det applikationen, der er problemet.
Almindelige årsager, og hvordan du løser dem
Applikationsprocessen er gået ned eller genstarter
Den hyppigste årsag. Processen bag proxyen løb tør for hukommelse, ramte en uhåndteret exception eller blev dræbt, og proxyen har ikke noget at tale med. nginx logger det klart og tydeligt:
connect() failed (111: Connection refused) while connecting to upstream,
upstream: “http://127.0.0.1:3000/checkout”
Tjek, om processen kører, og hvorfor den stoppede:
systemctl status myapp
journalctl -u myapp –since “30 min ago”
dmesg -T | grep -i “killed process”
En linje fra kernens out-of-memory killer betyder, at serveren løb tør for hukommelse. En genstart får sitet op igen, men den egentlige løsning er mere hukommelse, færre workers eller en fundet og rettet hukommelseslækage. Sørg for, at tjenesten genstarter af sig selv efter et nedbrud, for eksempel med Restart=on-failure i dens systemd-unit.
PHP-FPM er nede eller løbet tør for workers
På PHP-sites sender nginx forespørgsler videre til PHP-FPM via en socket eller port. Hvis PHP-FPM er stoppet, socket-stien er forkert, eller socketens rettigheder holder nginx ude, returnerer hver PHP-side 502:
connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory)
Den meddelelse kommer som regel efter en PHP-opgradering: nginx peger stadig på den gamle versions socket. Peg fastcgi_pass på den nye socket, og genindlæs nginx. Hvis loggen i stedet siger server reached pm.max_children, er alle workers optaget, ofte fordi de venter på en langsom database eller et eksternt API. Hæv kun grænsen, hvis serveren har hukommelse til overs; ellers så find ud af, hvad der holder dine workers beskæftiget.
Forkert upstream-adresse eller port
Efter en migrering, et genbygget container-image eller en ændret port sender proxyen måske stadig videre til den gamle adresse. Fejlloggen viser den adresse, den prøvede. Sammenlign den med, hvor applikationen faktisk lytter:
ss -ltnp | grep -E ‘:(3000|8000|9000)’
I Docker og Kubernetes er årsagen ofte et servicenavn, der ikke længere kan slås op, en container, der lytter på 127.0.0.1 inde i containeren i stedet for 0.0.0.0, eller et readiness-tjek, der markerer alle pods som ikke klar.
Upstream lukkede forbindelsen for tidligt
upstream prematurely closed connection while reading response header betyder, at applikationen tog imod forespørgslen og derefter lagde på. Typiske årsager er et nedbrud midt i forespørgslen, en worker, der blev dræbt for at overskride sin egen tidsgrænse, for eksempel Gunicorns –timeout eller PHP’s max_execution_time, og keep-alive-forbindelser, som applikationen lukker tidligere, end proxyen forventer. Afstem dine timeouts, så proxyen venter lidt længere end applikationen, aldrig omvendt, og se på, hvilke forespørgsler der er langsomme nok til at ramme grænsen.
For store svar-headers
Store cookies eller mange Set-Cookie-headers kan fylde mere end nginx’ buffer til upstreamens svar-headers. nginx logger så upstream sent too big header while reading response header from upstream og returnerer 502. Hæv bufferne med omtanke:
proxy_buffer_size 16k;
proxy_buffers 8 16k;
# for PHP-FPM
fastcgi_buffer_size 32k;
fastcgi_buffers 8 16k;
Find derefter ud af, hvorfor dine headers voksede. En cookie, der vokser ved hvert besøg, er en fejl, der er værd at rette.
CDN’et kan ikke tale med din origin
Når et CDN eller en load balancer returnerer 502, så tjek, hvad der står mellem den og din server. En firewall, der blokerer CDN’ets adresseområder, et origin-certifikat, som CDN’et ikke accepterer, en origin, der kun taler HTTP/1.0 eller lukker forbindelser for ivrigt, eller en DNS-post, der peger på en gammel server, ender alle på samme måde. Test originen direkte som vist ovenfor, og tjek firewallen og TLS-indstillingerne i begge ender.
502-fejl under deploys
Hvis 502-fejl dukker op i ti eller tyve sekunder ad gangen og altid omkring en release, er det selve deployet, der forårsager dem. Den gamle proces stopper, den nye er et par sekunder om at starte, og alle forespørgsler midt imellem fejler. Løsningen er en release-rækkefølge, hvor der altid er noget, der er klar til at svare:
Start den nye version ved siden af den gamle.
Vent, til dens health check består. Vores guide til at bygge et health check-endpoint viser, hvad det tjek bør teste.
Skift trafikken over til den nye version.
Lad den gamle version gøre de forespørgsler færdige, den har, og stop den derefter.
Procesmanagere og orkestreringsværktøjer understøtter det som rolling eller zero-downtime reloads. Brug dem i stedet for en almindelig genstart.
Sådan fanger overvågning 502-fejl
En 502 er ofte kortvarig. Et deploy giver tyve sekunders fejl, en worker går ned og genstarter, en cache skjuler problemet for de fleste besøgende. Når nogen åbner sitet, virker det igen, men en kunde midt i en checkout så fejlen.
En oppetidsovervågning henter dine sider efter en fast plan og registrerer statuskoden og svartiden for hvert tjek. En 502 er et fejlet tjek. Det afgørende er, hvad der sker bagefter:
Bekræft fejlen. En enkelt fejlet forespørgsel kan være et blip. Uptimecheck tjekker helt ned til hvert minut fra Stockholm, London og New York og bekræfter hver fejl fra en anden lokation, før en hændelse oprettes, så en enkeltstående nulstilling ikke vækker nogen.
Vis beviserne. Hændelsen indeholder det fejlende svar, så du ser statuskoden, server-headeren og fejlsiden, og et skærmbillede af det, de besøgende så. Når serveren slet ikke svarede, får du i stedet netværksstien.
Nå de rigtige personer. Alarmer sendes til e-mail, Slack, Microsoft Teams, PagerDuty, webhooks og de andre alarmkanaler, dit team bruger.
Overvåg mere end forsiden. Forsiden er ofte cachet af et CDN og bliver ved med at virke, mens checkout, login og API’et returnerer 502. Tilføj oppetidsovervågninger for de sider, der tjener penge, og API-overvågninger for de endpoints, dine apps kalder. Når 502-fejlen kommer fra en applikation, der løb tør for hukommelse, viser serverovervågning hukommelseskurven ved siden af nedbruddet.
Tjekliste til 502-fejl
Læs server-headeren og fejlsiden for at se, hvilket lag der returnerede 502.
Send forespørgsler direkte til originen og applikationens port for at indsnævre det.
Læs proxyens fejllog for samme tidsstempel: afvist, lukket for tidligt eller for stor header.
Tjek, at applikationsprocessen kører, og hvorfor den stoppede, hvis den ikke gør.
Sammenlign upstream-adressen, socketen og porten med, hvor applikationen lytter.
Afstem timeouts, så proxyen venter længere end applikationen.
Deploy ved at starte den nye version, før du stopper den gamle.
Overvåg vigtige sider og endpoints hvert minut, og bekræft hver fejl, før der sendes alarm.