Blog

Kako smo spustili deploy na nula grešaka 502

Svaki put kada smo objavljivali Mythexov backend, nekoliko zahteva je palo sa 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: samoizlečujući watchdog koji se borio protiv naših deploya i razmak između trenutka kada server prestane da sluša i trenutka kada balanser prestane da mu šalje saobraćaj. Kroz tri uzastopna produkciona deploya posle 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 jedan server po jedan: isprazni stare kontejnere, pokrene nove i prelazi na sledeći. Watchdog na svakom serveru proverava da li su kontejneri podignuti i ponovo pokreće sve što nije, kako bi se proces koji je pao u 3 ujutru vratio bez buđenja ikoga.

Oba su razumna sama za sebe. Zajedno nisu funkcionisala.

Problem 1: watchdog se utrkivao sa deployom

Watchdog je radio jednom u minut i „lečio“ posle jedne neuspele provere zdravlja. Deploy namerno prazni servise do 150 sekundi, a tokom tog vremena provera zdravlja treba da padne. Zato je watchdog reagovao tokom svakog deploya.

Najčešće je izgubio trku bez posledica. Jednom je pobedio: prepisao je compose fajl (opis koji kontejneri treba da rade) usred deploya i ostavio server bez gateway kontejnera, dok je deploy job prijavio uspeh.

Popravke:

  • Jedna brava. Deploy sada uzima isti fajl-zaključavanje kao bootstrap skripta servera, pa watchdog i deploy nikada ne mogu da rade u isto vreme.
  • Četiri štrajka, a ne jedan. Watchdog treba četiri uzastopne neuspele provere pre nego što reaguje. Servis koji se prazni više ne izgleda kao mrtav.
  • Jedna definicija. Compose fajl sada ima tačno jedan izvor, objavljen na servere, umesto kopija koje su mogle da se razilaze.
  • Proveri, ne veruj. Deploy job više ne prolazi zato što je komanda vratila rezultat. Pre nego što uspe, proverava API, orkestrator, gateway i publish worker na svakom serveru.

Problem 2: server je otišao pre nego što je saobraćaj otišao

Drugi problem je bio tiši. Kada deploy isprazni server, server na health endpointu počne da vraća 503 kako bi ga balanser izbacio iz rotacije. Naš je to radio 5 sekundi, pa se gasio.

Ali ALB je proveravao zdravlje samo povremeno i tražio je više uzastopnih neuspeha pre nego što prestane da šalje saobraćaj cilju, do otprilike 60 sekundi od početka do kraja. Zato je balanser oko 55 sekundi i dalje slao prave zahteve serveru koji je već prestao da sluša. To su bila naša 502.

Popravka je bila da se dve vremenske linije usklade:

  • Target grupa sada proverava svakih 5 sekundi i označava cilj kao nezdrav posle 2 neuspeha, otprilike 10 sekundi da se problem primeti.
  • Pražnjenje nastavlja da opslužuje prave zahteve 15 sekundi posle početka neuspelih provera zdravlja, tako da uvek postoji preklapanje.
  • Ova podešavanja žive u skripti koja podiže infrastrukturu, a ne u konzoli koju je neko jednom kliknuo.

Da brojevi drže jedni druge

Ovakvi timeouti zavise jedan od drugog. Pražnjenje mora da traje duže od vremena koje balanseru treba da primeti problem; pražnjenje plus gašenje mora da se završi pre nego što se kontejner prinudno ubije. Lako je da neko za šest meseci promeni jedan broj i tiho ponovo uvede grešku.

Zato smo te odnose zapisali kao testove: pražnjenje mora biti duže od intervala provere zdravlja pomnoženog pragom neuspeha; vreme do ponovnog označavanja kao zdrav mora ostati kratko; ceo period pražnjenja mora da stane u period milosti za zaustavljanje kontejnera. Ako promenite jedan broj bez ostalih, CI pada. Testirali smo i same testove mutacijama: svaki broj smo promenili na pogrešnu vrednost i proverili da li ga je neki test uhvatio.

Merenje deploya lako je pogrešiti

Naše prvo merenje je reklo da je čist deploy oko 3% pokvaren. Nije bio. Brojali smo svaki odgovor koji nije 200, a 503 sa health endpointa tokom pražnjenja nije greška. To je pražnjenje koje radi svoj posao, govoreći balanseru da ne bira taj server dok on i dalje opslužuje prave zahteve.

Ono što korisnici osete jeste 502: zahtev nije stigao ni do čega. Brojanje samo tih slučajeva dalo je pravu sliku: 10, pa 6, pa 0 kroz tri produkciona deploya.

Šta smo izvukli

  • Samoizlečenje mora znati za planirani prekid. Watchdog koji ne može da razlikuje deploy od pada će se pre ili kasnije boriti protiv deploya.
  • Pražnjenje je rukovanje. Server mora da nastavi da opslužuje dok balanser ne dokaže da je prestao da šalje saobraćaj, a to vreme se podešava na balanseru, ne na serveru.
  • Invarijante zapisujte kao testove. Operativni brojevi se razilaze. Testovi koji ih povezuju jedne s drugima ne dozvoljavaju to.
  • Odlučite šta merite pre merenja. „Greške“ su bile pogrešna metrika; „zahtevi koji nisu stigli ni do čega“ bila je prava.

Ako objavljujete aplikaciju na Mythexu, ništa od ovoga vam nije vidljivo, i u tome je poenta. Srodno: kako vaša objavljena aplikacija ostaje dostupna dok je ponovo objavljujete.

Mythex · Pricing · Pravite bilo šta uz AI · Šabloni za sajtove i aplikacije · Mythex u poređenju · Rečnik pojmova za pravljenje aplikacija uz AI · Besplatni alati za pravljenje aplikacija uz AI · 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 မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)