Hvatanje aplikacija koje padaju odmah posle objavljivanja
Dana 25. septembra tri objave su označene kao uspešne iako je API aplikacije padao nekoliko sekundi posle svakog pokretanja. Pošto su „uspele”, vraćanje nije pokrenuto; pozadinska provera ih je kasnije nekoliko minuta označila kao neuspele, i ceo sajt je prešao na 404. Provera zdravlja brojala je padove u listi događaja hosting platforme — koja uvek sadrži samo poslednjih pet događaja po mašini, pa petlja padova drži listu punom i brojač nikad ne raste. Sada umesto broja poredi vreme najnovijeg pada, a objava koja ulazi u petlju padova ne uspeva i vraća prethodnu verziju.
Šta objava čeka
Kada objavite aplikaciju sa backend-om na Mythex-u, nova verzija se postavlja na mašine naše hosting platforme, a provera zdravlja odlučuje da li je objava stupila na snagu ili je neuspešna. Ako jeste neuspešna, vraćanje vraća prethodnu verziju.
Teški deo je to što „pokrenuto” nije isto što i „služi”. Platforma prijavljuje mašinu kao pokrenutu čim se digne. Aplikacija koja padne sekundu posle pokretanja odmah se ponovo pokreće, pa u sledećem trenutku ponovo izgleda kao pokrenuta. Zato je provera zdravlja tokom vremena dobila nekoliko slojeva:
- Pogledaj dva puta. Kada mašina izgleda pokrenuta, sačekaj kratko i pogledaj ponovo. Pad pri pokretanju često pukne već na drugom pogledu.
- Pazi na petlje padova. Ako platforma prijavi da se mašina stalno rušila i da je odustala od ponovnog pokretanja, objava ne uspeva.
- Broj padova od početka objave. Dva „pokrenuta” pogleda mogu da obuhvate ponovno pokretanje. Zato, ako je od početka ove objave bilo ijednog pada, pogledaj treći put; ako ima više padova nego pri prethodnom pogledu, aplikacija ne ostaje podignuta.
Treća provera je ona koja je ovde pukla.
Zašto je brojač ostajao isti
Informacije o padovima dolaze iz liste događaja svake mašine: pokretanja, izlazi, ponovna pokretanja. Platforma čuva samo poslednjih pet događaja po mašini.
Zamislite aplikaciju koja pada 2,5 sekunde posle svakog pokretanja, kao jedna od njih. Svaki ciklus dodaje jedan pad i jedno pokretanje. Posle nekoliko ciklusa lista je puna. Od tada, svaki novi događaj gura neki stari van. Lista klizi unapred, ali uvek sadrži otprilike isti spoj: nekoliko padova, nekoliko pokretanja.
Zato „koliko je padova od početka objave” vraća isti broj pri svakom pogledu. Drugi pogled video je, recimo, dva pada. Treći pogled takođe je video dva — drugačija padanja, ali isti broj. Provera je zaključila da je rušenje prestalo i propustila je objavu.
Tako se dogodilo tri puta 25. septembra, na dve aplikacije. Svaki put:
- objava je označena kao aktivna,
- vraćanje nije pokrenuto, jer ništa nije palo,
- naš reconciler, pozadinski posao koji naknadno proverava deploymente, nekoliko minuta kasnije označio je deployment kao neuspešan,
- i ceo sajt je vratio 404.
Objava koja ne uspe na vreme može da se oporavi: vraćanje vraća prethodnu verziju. Objava koja padne nekoliko minuta kasnije, posle što je proglašena uspešnom, već je preskočila vraćanje.
Kako smo to našli
Reprodukovali smo lokalno: uzeli smo radni API, pustili ga da zaspi, pa ga ponovo objavili sa izmenom koja pada pri pokretanju. Provera zdravlja ga je označila kao aktivnog.
To se poklopilo sa produkcijom: u svakoj od tri objave aplikacija je umirala nekoliko sekundi posle svakog pokretanja, ali broj padova koji je provera upoređivala nikad nije porastao između pogleda.
Popravka: uporedi najnoviji pad, a ne broj
Umesto da broji padove, provera sada gleda vreme najnovijeg pada od početka objave.
Ako drugi pogled pokaže bilo koji pad od početka objave, provera čeka i pogleda treći put. Ako je najnoviji pad pri trećem pogledu kasniji od najnovijeg pada pri drugom, mašina se ponovo srušila u međuvremenu. Ne ostaje podignuta, a objava ne uspeva uz poruku da se mašina ponavljano rušila od objavljivanja i da se i dalje ponovo pokreće.
Ovo radi bez obzira na to koliko je lista događaja kratka. Klizni prozor od pet događaja može da sakrije koliko je bilo padova, ali ne može da sakrije da se upravo dogodio novi — najnoviji događaj je uvek onaj koji ostaje.
Sa ovom izmenom, lokalna reprodukcija se ponaša ispravno: objava ne uspeva i prethodna slika se vraća. Postoji i test koji simulira ponašanje platforme — svaki pogled dodaje pad i pokretanje i skraćuje listu na pet — i proverava da je presuda neuspeh, a ne prolaz.
Šta smo iz ovoga izvukli
- Poznajte oblik podataka koje brojite. Brojanje nad ograničenom listom prestaje da znači išta kada se lista napuni. Ograničenje nije bilo skriveno; samo nismo projektovali proveru oko njega.
- Radije pitajte „da li se desilo nešto novo?” nego „koliko se desilo?” Najnoviji vremenski žig preživljava skraćivanje. Ukupan broj ne.
- Kasan neuspeh gori od ranog. Ista pokvarena verzija je bezopasna ako objava ne uspe i vrati se, a ruši sajt ako je prvo proglašena uspešnom.
- Reprodukujte u stvarnim uslovima. Greška je zahtevala mašinu koja se već dovoljno puta srušila da popuni listu događaja. Jedan brz pad u testu ne bi to pokazao.
Ova popravka se nadovezuje na drugu iz istog dana, koja je osigurala da vraćanje vrati staru verziju umesto da je obriše: neuspela ponovna objava nikad ne briše radni backend. Ako vaša aplikacija ne uspeva da se objavi jer pada pri pokretanju, dokumentacija o rešavanju problema pri objavi i naš vodič o debagovanju aplikacije koju je napravio AI su dobra mesta za početak.