Blog

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

Svaki put kad bismo deployali backend Mythexa, nekoliko zahtjeva pali bi s 502 Bad Gateway. Nije ih bilo mnogo, ali 502 tijekom deploya znači da klik nekoga nije ništa učinio ili da se build koji je netko gledao na trenutak zaustavio. Problem smo pratili do dva odvojena uzroka: samoliječeći watchdog koji se borio protiv naših deployeva i razmak između trenutka kad server prestane slušati i trenutka kad load balancer prestane slati promet na njega. U tri uzastopna produkcijska deploya nakon popravaka broj se spustio s 10 na 6 i na 0.

Postavka

Naš API i orkestrator rade kao kontejneri na maloj grupi servera iza AWS Application Load Balancera (ALB). Deploy ažurira jedan server po jedan: isprazni stare kontejnere, pokrene nove i prelazi dalje. Watchdog na svakom serveru provjerava rade li kontejneri i ponovno pokreće sve što ne radi. Postoji da se srušeni proces u 3 ujutro vrati bez buđenja ikoga.

Oba su razumna sama za sebe. Zajedno nisu.

Problem 1: watchdog se natjecao s deployem

Watchdog je radio jednom u minuti i „liječio” na jednu neuspjelu provjeru zdravlja. Deploy namjerno prazni servise do 150 sekundi, a tijekom toga provjera zdravlja treba pasti. Watchdog je zato reagirao tijekom svakog deploya.

Veći dio vremena izgubio bi utrku bezopasno. Jednom ju je dobio: prepisao je compose datoteku (opis kontejnera koji trebaju raditi) usred deploya i ostavio server bez ijednog gateway kontejnera, dok je deploy job javljao uspjeh.

Popravci:

  • Jedan lock. Deploy sada uzima isti file lock kao bootstrap skripta servera, pa watchdog i deploy nikad ne mogu raditi istovremeno.
  • Četiri udarca, a ne jedan. Watchdog treba četiri uzastopne neuspjele provjere prije nego što reagira. Servis koji se prazni više ne izgleda mrtav.
  • Jedna definicija. Compose datoteka sada ima točno jedan izvor, objavljen na servere, umjesto kopija koje su mogle odstupiti.
  • Provjerite, ne vjerujte. Deploy job više ne prolazi zato što je naredba vratila uspjeh. Prije nego što može uspjeti, provjerava API, orkestrator, gateway i publish worker na svakom serveru.

Problem 2: server je otišao prije prometa

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

ALB je, međutim, provjeravao zdravlje samo povremeno i trebao je nekoliko uzastopnih neuspjelih provjera prije nego što je prestao slati na metu, do otprilike 60 sekundi od početka do kraja. Zato je load balancer oko 55 sekundi i dalje slao stvarne zahtjeve serveru koji je već prestao slušati. To su bile naše 502 greške.

Rješenje je bilo uskladiti dvije vremenske linije:

  • Ciljna grupa sada provjerava svakih 5 sekundi, a metu označava nezdravom nakon 2 neuspjeha, što znači oko 10 sekundi do otkrivanja.
  • Pražnjenje nastavlja posluživati stvarni promet 15 sekundi nakon što krene padati provjera zdravlja, pa uvijek postoji preklapanje.
  • Te postavke žive u skripti koja pruža infrastrukturu, a ne u konzoli koju je netko jednom kliknuo.

Da brojevi drže jedni druge

Ovakvi timeouti ovise jedan o drugome. Pražnjenje mora trajati dulje od vremena koje balanceru treba da primijeti; pražnjenje plus gašenje mora završiti prije nego što se kontejner prisilno ubije. Lako je da netko za šest mjeseci promijeni jedan broj i tiho ponovno uvede grešku.

Zato smo te odnose zapisali kao testove: pražnjenje mora biti dulje od intervala provjere pomnoženog s pragom neuspjeha; vrijeme do ponovnog označavanja kao zdravog mora ostati kratko; cijelo pražnjenje mora stati unutar stop grace perioda kontejnera. Promijenite jedan broj bez ostalih i CI pada. Testirali smo i same testove mutacijom: svaki broj smo promijenili u krivu vrijednost i provjerili hvata li ga test.

Mjerenje deploya lako je pogrešno

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 tijekom 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 poslužuje stvarne zahtjeve.

Korisnik osjeća 502: zahtjev nije stigao nigdje. Brojanje samo tih grešaka dalo je pravu sliku: 10, pa 6, pa 0 kroz tri produkcijska deploya.

Što smo iz toga izvukli

  • Samoliječenje mora znati za planirani prekid. Watchdog koji ne razlikuje deploy od pada prije ili kasnije će se boriti s deployem.
  • Pražnjenje je rukovanje. Server mora nastaviti poslužiti dok load balancer nije dokazano prestao slati promet, a to vrijeme se postavlja na balanceru, a ne na serveru.
  • Invarijante zapišite kao testove. Operativni brojevi s vremenom odstupaju. Testovi koji ih povezuju jedne s drugima ne odstupaju.
  • Odlučite što mjerite prije mjerenja. „Greške” su bila kriva metrika; „zahtjevi koji nisu stigli nigdje” bila je prava.

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

Mythex · Pricing · Izradite bilo što uz AI · Predlošci za web stranice i aplikacije · Mythex u usporedbi · Rječnik izrade aplikacija uz AI · Besplatni alati za izradu aplikacija uz AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी 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 简体中文 繁體中文(香港) 繁體中文(台灣)