Blogg

Slik fikk vi deployene ned til null 502-feil

Hver gang vi deployet Mythex sin backend, feilet et lite antall forespørsler med 502 Bad Gateway. Ikke mange — men en 502 under en deploy betyr at noens klikk ingenting gjorde, eller at et bygg noen fulgte med på stoppet opp et øyeblikk. Vi sporet det til to separate problemer: en selvhelende watchdog som kjempet mot deployene våre, og et gap mellom når en server sluttet å lytte og når lastbalanseren sluttet å sende den trafikk. På tre påfølgende produksjonsdeployer etter rettelsene gikk antallet fra 10 til 6 til 0.

Oppsettet

API-et og orkestratoren vår kjører som containere på en liten gruppe servere bak en AWS Application Load Balancer (ALB). En deploy oppdaterer én server om gangen: den tømmer de gamle containerne, starter nye og går videre. En watchdog på hver server sjekker at containerne kjører, og starter på nytt det som ikke gjør det. Den finnes slik at en prosess som krasjer klokken tre om natten kommer tilbake uten at noen må vekkes.

Begge deler er fornuftig hver for seg. Sammen fungerte de ikke.

Problem 1: watchdogen konkurrerte med deployen

Watchdogen kjørte én gang i minuttet og «helbredet» ved én mislykket helsesjekk. En deploy tømmer med vilje tjenester i opptil 150 sekunder — og i den perioden skal en helsesjekk feile. Så watchdogen slo inn under hver eneste deploy.

Oftest tapte den kappløpet uten skade. En gang vant den: den skrev om compose-filen (beskrivelsen av hvilke containere som skal kjøre) midt i en deploy, og etterlot en server uten gateway-container i det hele tatt — mens deploy-jobben rapporterte suksess.

Rettelsene:

  • Ett lås. Deployen tar nå samme fillås som serverens oppstartsskript, slik at watchdogen og en deploy aldri kan kjøre samtidig.
  • Fire feil, ikke én. Watchdogen trenger fire påfølgende mislykkede sjekker før den handler. En tjeneste som tømmes ser ikke lenger død ut.
  • Én definisjon. Compose-filen har nå én kilde, publisert til serverne, i stedet for kopier som kunne drive fra hverandre.
  • Bekreft, ikke stol på. Deploy-jobben består ikke lenger bare fordi en kommando returnerte. Den sjekker API-et, orkestratoren, gatewayen og publiseringsarbeideren på hver server før den kan lykkes.

Problem 2: serveren forsvant før trafikken gjorde det

Det andre problemet var stillere. Når en deploy tømmer en server, svarer serveren på helsesjekk-endepunktet sitt med 503, slik at lastbalanseren tar den ut av rotasjonen. Vår gjorde det i 5 sekunder, og stengte så ned.

Men ALB-en sjekket helsen bare med visse mellomrom, og trengte flere mislykkede sjekker på rad før den sluttet å rute til et mål — opptil omtrent 60 sekunder totalt. Så i omtrent 55 sekunder fortsatte lastbalanseren å sende ekte forespørsler til en server som allerede hadde sluttet å lytte. Det var våre 502-feil.

Løsningen var å få de to tidslinjene til å stemme overens:

  • Målgruppen sjekker nå hvert 5. sekund og markerer et mål som usunt etter 2 feil — omtrent 10 sekunder på å oppdage det.
  • Tømmingen fortsetter å betjene ekte trafikk i 15 sekunder etter at den begynner å feile helsesjekker, slik at det alltid er overlapp.
  • Disse innstillingene ligger i skriptet som klargjør infrastrukturen, ikke i en konsoll noen klikket seg frem til én gang.

Å få tallene til å holde hverandre

Tidsavbrudd som disse avhenger av hverandre. Tømmingen må vare lenger enn balanseren trenger for å oppdage problemet, og tømming pluss nedstenging må bli ferdig før containeren tvangsstoppes. Det er lett at noen endrer ett tall om seks måneder og ubemerket innfører feilen igjen.

Så vi skrev disse sammenhengene ned som tester: tømmingen må være lengre enn helsesjekkintervallet ganger feilterskelen; tiden til å bli markert som frisk igjen må holdes kort; hele tømmingen må få plass innenfor containerens stoppfrist. Endrer du ett tall uten de andre, feiler CI. Vi testet selve testene med mutasjoner — endret hvert tall til en feil verdi og kontrollerte at en test fanget det.

Å måle en deploy er lett å gjøre feil

Vår første måling sa at en ren deploy var omtrent 3 % ødelagt. Den var det ikke. Vi telte hver respons som ikke var 200, og en 503 fra et helsesjekk-endepunkt under tømming er ikke en feil — det er tømmingen som gjør jobben sin og forteller balanseren at den ikke skal velge den serveren mens den fortsatt betjener ekte forespørsler.

Det brukerne merker er en 502: forespørselen nådde ingenting. Å telle bare dem ga det virkelige bildet — 10, deretter 6, deretter 0 på tvers av tre produksjonsdeployer.

Det vi tok med oss

  • Selvheling må kjenne til planlagt nedetid. En watchdog som ikke kan skille en deploy fra et krasj, vil før eller siden kjempe mot deployen.
  • Tømming er et håndtrykk. Serveren må fortsette å betjene til lastbalanseren med sikkerhet har sluttet å sende trafikk, og den tidsstyringen settes på balanseren, ikke på serveren.
  • Skriv invarianter som tester. Driftstall glir. Tester som relaterer dem til hverandre gjør ikke det.
  • Bestem hva du måler før du måler. «Feil» var feil mål; «forespørsler som nådde ingenting» var det riktige.

Hvis du publiserer en app på Mythex, er ingenting av dette synlig for deg — og det er poenget. Relatert: hvordan den publiserte appen din forblir oppe mens du publiserer på nytt.

Mythex · Pricing · Bygg hva som helst med KI · Maler for nettsider og apper · Mythex sammenlignet · Ordliste for app-bygging med KI · Gratis verktøy for app-bygging med KI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)