Blog

Kako smo došli do nula 502 grešaka pri deployu

Svaki put kada smo deployovali Mythex backend, nekoliko zahtjeva je palo s 502 Bad Gateway. Nije ih bilo mnogo, ali 502 tokom deploya znači da je nečiji klik ostao bez efekta, ili da se build koji je neko pratio na trenutak zaglavio. Pratili smo to do dva odvojena problema: samoizlječivog watchdoga koji se borio s našim deployima, i praznine između trenutka kada server prestane slušati i trenutka kada load balancer prestane da mu šalje saobraćaj. Kroz tri uzastopna produkciona deploya nakon popravki, broj je pao sa 10 na 6, pa na 0.

Postavka

Naš API i orkestrator rade kao kontejneri na maloj grupi servera iza AWS Application Load Balancera (ALB). Deploy ažurira po jedan server: isprazni stare kontejnere, pokrene nove i prelazi na sljedeći. Watchdog na svakom serveru provjerava da li su kontejneri podignuti i ponovo pokreće sve što ne radi. Postoji da bi se srušeni proces u 3 ujutro vratio bez da iko bude probuđen.

Oba su razumna sama za sebe. Zajedno nisu bila.

Problem 1: watchdog se takmičio s deployom

Watchdog je radio jednom u minuti i „liječio“ na jednu neuspješnu provjeru. Deploy namjerno prazni servise do 150 sekundi, tokom kojih provjera treba da padne. Zato se watchdog aktivirao tokom svakog pojedinačnog deploya.

Većinu vremena je gubio trku bez štete. Jednom ju je dobio: prepisao je compose fajl (opis kontejnera koji treba da rade) usred deploya i ostavio server bez gateway kontejnera uopšte, dok je deploy job prijavljivao uspjeh.

Popravke:

  • Jedan lock. Deploy sada uzima isti lock fajla kao bootstrap skripta servera, pa watchdog i deploy nikada ne mogu raditi istovremeno.
  • Četiri pogotka, a ne jedan. Watchdog čeka četiri uzastopne neuspješne provjere prije nego što djeluje. Servis koji se prazni više ne izgleda kao mrtav.
  • Jedna definicija. Compose fajl sada ima tačno jedan izvor, objavljen na servere, umjesto kopija koje su mogle da se raziđu.
  • Provjerite, ne vjerujte. Deploy job više ne prolazi zato što je komanda vratila uspjeh. Provjerava API, orkestrator, gateway i publish worker na svakom serveru prije nego što može uspjeti.

Problem 2: server je otišao prije saobraćaja

Drugi problem je bio tiši. Kada deploy isprazni server, server počinje da odgovara na svoj health endpoint s 503 kako bi ga load balancer izbacio iz rotacije. Naš je to radio 5 sekundi, a zatim se ugasio.

Ali ALB je provjeravao zdravlje samo povremeno i trebao je nekoliko neuspjeha zaredom prije nego što prestane da šalje saobraćaj nekom targetu, do otprilike 60 sekundi od početka do kraja. Zato je load balancer oko 55 sekundi nastavljao da šalje stvarne zahtjeve serveru koji je već prestao da sluša. To su bile naše 502 greške.

Popravka je bila da se dvije vremenske linije usklade:

  • Target grupa sada provjerava svakih 5 sekundi i označava target kao nezdrav nakon 2 neuspjeha, otprilike 10 sekundi da to primijeti.
  • Pražnjenje nastavlja da servira stvarni saobraćaj 15 sekundi nakon što počne da neuspješno provjerava zdravlje, pa uvijek postoji preklapanje.
  • Ta podešavanja žive u skripti koja pripremlja infrastrukturu, a ne u konzoli koju je neko jednom kliknuo.

Da brojevi drže jedni druge

Vremenska ograničenja ovakvog tipa zavise jedno od drugog. Pražnjenje mora trajati duže od vremena koje balanceru treba da primijeti; pražnjenje plus gašenje mora završiti prije nego što kontejner bude prisilno ubijen. Lako je da neko promijeni jedan broj za šest mjeseci i tiho ponovo uvede grešku.

Zato smo te odnose zapisali kao testove: pražnjenje mora biti duže od intervala provjere zdravlja pomnoženog s pragom neuspjeha; vrijeme do ponovnog označavanja kao zdravog mora ostati kratko; ukupno pražnjenje mora stati u grace period zaustavljanja kontejnera. Promijenite jedan broj bez ostalih i CI pada. Testirali smo i same testove mutacijama: svaki broj smo promijenili u pogrešnu vrijednost i provjerili da ga neki test uhvati.

Mjerenje deploya lako je pogrešno uraditi

Naše prvo mjerenje reklo je da je čist deploy pokvaren oko 3 %. Nije bio. Brojali smo svaki odgovor koji nije 200, a 503 s health endpointa tokom pražnjenja nije greška. To je pražnjenje koje radi svoj posao, govoreći balanceru da ne bira taj server dok on i dalje služi stvarne zahtjeve.

Ono što korisnici osjete je 502: zahtjev nije stigao nigdje. Brojanje samo tih grešaka dalo je pravu sliku: 10, pa 6, pa 0 kroz tri produkciona deploya.

Šta smo iz toga izvukli

  • Samoizlječenje mora znati za planirani prekid. Watchdog koji ne može razlikovati deploy od pada će se prije ili kasnije boriti s deployom.
  • Pražnjenje je rukovanje. Server mora nastaviti da servira dok load balancer ne bude dokazano prestao da šalje saobraćaj, a to vrijeme se postavlja na balanceru, ne na serveru.
  • Invarijante kodirajte kao testove. Operativni brojevi zastarijevaju. Testovi koji ih povezuju međusobno to ne rade.
  • Odlučite šta mjerite prije mjerenja. „Greške“ su bila pogrešna metrika; „zahtjevi koji nisu stigli nigdje“ bila je pravilna.

Ako objavljujete aplikaciju na Mythexu, ništa od ovoga vam nije vidljivo, što je i cilj. Povezano: kako vaša objavljena aplikacija ostaje aktivna dok je ponovo objavljujete.

Mythex · Pricing · Izradite bilo šta uz AI · Šabloni za web stranice i aplikacije · Mythex u poređenju · Rječnik izrade aplikacija uz AI · Besplatni alati za izradu aplikacija uz AI · English

English አማርኛ العربية Български বাংলা 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 မြန်မာ Norsk bokmål 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 简体中文 繁體中文(香港) 繁體中文(台灣)