Hvatanje aplikacija koje se sruše odmah nakon objave
Dana 25. rujna tri objave označene su kao uspješne, iako se API aplikacije srušio nekoliko sekundi nakon svakog pokretanja. Budući da su bile “uspješne”, vraćanje nije pokrenuto; pozadinska provjera ih je neko vrijeme kasnije označila kao neuspjele, a cijela stranica prešla je na 404. Provjera zdravlja brojala je padove u listi događaja hosting platforme, koja uvijek drži samo posljednjih pet događaja po stroju, pa petlja padova drži listu punom i brojanje nikad ne raste. Sada uspoređuje vrijeme najnovijeg pada, a objava koja se ponavljano ruši pada i vraća prethodnu verziju.
Na što objava čeka
Kad objavite aplikaciju s backendom na Mythexu, nova verzija se postavlja na strojeve naše hosting platforme, a provjera zdravlja odlučuje je li objava uspjela ili je pala. Ako je pala, vraćanje vraća prethodnu verziju.
Teški dio je što “pokrenuto” nije isto što i “poslužuje”. Platforma stroj označava kao pokrenut čim je podignut. Aplikacija koja se sruši sekundu nakon pokretanja odmah se ponovno pokrene, pa ponovno izgleda kao pokrenuta. Zato je provjera zdravlja tijekom vremena dobila nekoliko slojeva:
- Gledaj dvaput. Nakon što stroj izgleda pokrenut, kratko pričekaj i pogledaj ponovno. Pad pri pokretanju često pukne već kod drugog pogleda.
- Traži petlje padova. Ako platforma javlja da se stroj kontinuirano rušio i da je prestala pokušavati ga ponovno pokrenuti, objava pada.
- Broji padove od početka objave. Dva “pokrenuto” pogleda mogu obuhvatiti ponovno pokretanje. Zato, ako se od početka ove objave dogodio bilo koji pad, gledaj još jednom; ako ima više padova nego pri prethodnom pogledu, aplikacija se ne održava.
Treća provjera je ona koja je ovdje zakazala.
Zašto je broj ostao isti
Informacije o padovima dolaze iz popisa događaja svakog stroja: pokretanja, izlazi, ponovna pokretanja. Platforma čuva samo posljednjih pet događaja po stroju.
Zamislite aplikaciju koja se ruši 2,5 sekunde nakon svakog pokretanja, kao jedna od njih. Svaki ciklus dodaje pad i pokretanje. Nakon nekoliko ciklusa popis je pun. Od tada svaki novi događaj gura jedan stari van. Popis klizi naprijed, ali uvijek sadrži otprilike istu mješavinu: nekoliko padova, nekoliko pokretanja.
Zato je “koliko je padova od početka objave” vraćalo isti broj pri svakom pogledu. Drugi pogled vidio je, recimo, dva pada. Treći pogled također je vidio dva pada, doduše druga, ali isti broj. Provjera je zaključila da rušenje prestalo i propustila objavu.
To se dogodilo tri puta 25. rujna, na dvije aplikacije. Svaki put:
- objava je označena kao aktivna,
- vraćanje se nije pokrenulo, jer ništa nije palo,
- naš reconciler, pozadinski posao koji provjerava objave naknadno, označio je objavu kao neuspjelu nekoliko minuta kasnije,
- i cijela stranica vratila je 404.
Objava koja pukne na vrijeme može se oporaviti: vraćanje vraća prethodnu verziju. Objava koja pukne nekoliko minuta kasnije, nakon što je proglašena uspjehom, već je preskočila vraćanje.
Kako smo to pronašli
Reproducirali smo lokalno: uzeli smo radni API, pustili ga da zaspi, pa ga ponovno objavili s izmjenom koja se ruši pri pokretanju. Provjera zdravlja ga je označila kao aktivnog.
To se poklapalo s produkcijom: u svakoj od tri objave aplikacija je umirala nekoliko sekundi nakon svakog pokretanja, ali broj padova koji je provjera uspoređivala nikad nije porastao između pogleda.
Ispravak: usporedi najnoviji pad, a ne broj
Umjesto brojanja padova, provjera sada gleda vrijeme najnovijeg pada od početka objave.
Ako drugi pogled pokaže bilo koji pad od početka objave, provjera čeka i gleda treći put. Ako je najnoviji pad na trećem pogledu noviji od najnovijeg pada na drugom, stroj se ponovno srušio u međuvremenu. Ne održava se, a objava pada s porukom da se stroj od objave rušio više puta i da se još uvijek ponovno pokreće.
Ovo radi bez obzira koliko je kratka lista događaja. Klizni prozor od pet događaja može sakriti koliko je padova bilo, ali ne može sakriti da se upravo dogodio novi, jer je najnoviji događaj uvijek onaj koji ostaje.
S ovom promjenom lokalna reprodukcija se ponaša ispravno: objava pada i vraća se prethodna slika. Postoji i test koji simulira ponašanje platforme (svaki pogled dodaje pad i pokretanje i skraćuje listu na pet) i provjerava da je presuda neuspjeh, a ne uspjeh.
Što smo iz ovoga naučili
- Poznajte oblik podataka koje brojite. Brojanje na ograničenoj listi prestaje imati smisao kad se lista napuni. Ograničenje nije bilo skriveno; jednostavno nismo provjeru dizajnirali oko njega.
- Radije pitajte “je li se dogodilo nešto novo?” nego “koliko se toga dogodilo?” Najnoviji vremenski žig preživi skraćivanje. Ukupan broj ne preživi.
- Kasni neuspjeh gori od ranog. Ista pokvarena verzija je bezopasna ako objava pukne i vrati se, a ako se prvo proglasi uspjehom, ruši cijelu stranicu.
- Reproducirajte u stvarnim uvjetima. Greška je zahtijevala stroj koji se već dovoljno puta srušio da napuni listu događaja. Jedan brzi pad u testu to ne bi pokazao.
Ovaj ispravak nadopunjuje drugi iz istog dana, koji je osigurao da vraćanje vrati staru verziju umjesto da je obriše: neuspjelo ponovno objavljivanje nikad ne briše radni backend. Ako se vaša aplikacija ne objavljuje jer se ruši pri pokretanju, rješavanje problema pri objavi u dokumentaciji i naš vodič o debugiranju aplikacije izrađene AI-jem dobra su mjesta za početak.