Një ripublikim i dështuar nuk fshin kurrë një backend që funksionon
Më 25 shtator, një ripublikim i dështuar fshiu backend-in e një aplikacioni që kishte qenë live dhe që funksiononte për rreth dy orë e gjysmë. Kodi që zhbën një publikim të dështuar hiqte çdo aplikacion serveri që publikimi e kishte prekur, përfshirë edhe ata që po shërbenin para se të fillonte. Tani vetëm aplikacionet që i krijoi një publikim fshihen ndonjëherë; një aplikacion që ekzistonte më parë kthehet në versionin e saktë që po ekzekutonte para se të fillonte publikimi. Dy rregullime të tjera të po atij dite siguruan që zhbërja të ekzekutohet edhe kur vetë mjeti i vendosjes së platformës së hostimit dështon, dhe që një aplikacion i shëndetshëm të mos dështojë vetëm sepse ishte në gjumë.
Si publikohet një backend
Kur aplikacioni yt Mythex ka një backend — një API ose server, jo vetëm skedarë statikë — publikimi e ndërton nga një Dockerfile (një recetë që e paketon aplikacionin në një imazh) dhe e vendos atë imazh në makinat e platformës sonë të hostimit. Pastaj një kontroll shëndeti pret që versioni i ri të ngrihet dhe të qëndrojë në punë përpara se publikimi të shënohet si live.
Nëse diçka dështon gjatë rrugës, ekzekutohet një kthim mbrapsht (rollback) për ta zhbërë. Ta bësh drejt këtë kthim ka më shumë rëndësi se pothuajse çdo gjë tjetër në publikim, sepse ekzekutohet pikërisht kur diçka është tashmë duke shkuar keq.
Problemi 1: kthimi mbrapsht fshinte atë që duhej ta rikthente
Kthimi mbrapsht mbante një listë me aplikacionet e serverit ku publikimi ishte vendosur, dhe kur dështonte, i shkatërronte të gjitha. Kjo është e saktë për një publikim të parë: aplikacioni u krijua pak më parë, asgjë nuk varet nga ai, dhe fshirja e tij e lë gjërat ashtu si ishin.
Por është pikërisht e gabuar për një ripublikim. Aplikacioni ekzistonte tashmë dhe i shërbente vizitorëve realë. Më 25 shtator, një API aplikacioni që kishte qenë live për rreth dy orë e gjysmë u fshi nga një ripublikim që dështoi.
Në të njëjtin kod fshihej edhe një mënyrë tjetër dështimi, më e heshtur. Aty ku fshirja nuk arrinte të kryhej, imazhi i prishur i ri mbetej në makina — ndërsa ne i thonim pronarit se faqja e tij aktuale ishte ende live. Kur kontrolli i shëndetit mund të dështojë, imazhi i ri është vendosur tashmë në çdo makinë. Mos bërja e asgjëje nuk është e njëjta gjë me zhbërjen.
Rregullimi: fshi vetëm atë që ke krijuar, rikthe pjesën tjetër
Tani çdo publikim regjistron, për çdo aplikacion serveri që prek:
- nëse këtë publikim e krijoi, dhe
- nëse jo, cilin imazh po ekzekutonte pak para se të fillonte.
Kur dështon, çdo aplikacion merr një nga tre trajtimet:
- E krijoi këtë publikim: fshije, si më parë.
- Ekzistonte më parë, imazhi i mëparshëm njihet: vendos përsëri imazhin e mëparshëm me të njëjtën konfigurim. Nuk ka ndërtim — vetëm imazhi kthehet mbrapsht.
- Ekzistonte më parë, imazhi i mëparshëm nuk njihet: lëre ashtu. Një aplikacion ekzistues nuk fshihet kurrë, edhe kur nuk mund ta rikthejmë.
Këto rregulla janë një funksion i vogël i pastër me testet e veta, kështu që vendimi nuk mund të kthehet te "fshi gjithçka" pa që një test të dështojë.
Problemi 2: mjeti i vendosjes mund të dështonte përpara se ne të shkruanim si të zhbëhej
Pak pas atij rregullimi, gjetëm një boshllëk. Mjeti i vendosjes së platformës ekzekuton kontrollet e veta të shpejta: nëse makinat e reja rrëzohen, ai del me gabim. Por e bën këtë pasi imazhi i ri është tashmë në makina.
Kodi ynë e regjistronte një aplikacion për kthim mbrapsht vetëm pasi mjeti kthehej me sukses. Kur vetë mjeti e dështonte vendosjen, aplikacioni nuk ishte ende në listën e kthimit, kështu që asgjë nuk u rikthye. Në mjedisin tonë të stagingut, një ripublikim i prishur la të shërbente imazhin e prishur.
Rregullimi: regjistro zhbërjen para se të nisësh
Tani aplikacioni regjistrohet për kthim mbrapsht — me informacionin nëse u krijua dhe cilin imazh po ekzekutonte — sapo përgatitet, dhe përpara se çdo gjë të vendoset mbi të. Çka dështon më pas, kthimi di çfarë të rikthejë. E verifikuam lokalisht: një ripublikim i prishur dështoi në kontrollet e shpejta të vetë mjetit të vendosjes, dhe versioni i mëparshëm vazhdoi të përgjigjej.
Problemi 3: një aplikacion në gjumë u shënua si "nuk nisi kurrë"
Aplikacionet e publikuara në Mythex flenë kur janë pa aktivitet, për të kursyer kredit. Një ripublikim e lë një makinë në gjumë të ndaluar, kështu që kontrolli i shëndetit duhet ta zgjojë. Ai i kërkonte platformës ta nisë makinën një herë, dhe nuk i kushtonte vëmendje përgjigjes.
Më 25 shtator, ajo kërkesë e vetme për nisje nuk arriti askund. Një API i shëndetshëm mbeti i ndaluar gjatë gjithë kontrollit pesë-minutësh të shëndetit dhe u shënua si dështim me mesazhin "1 makinë nuk nisi kurrë (gjendja e fundit: stopped)".
Platforma ndonjëherë refuzon një nisje. Gjatë riprodhimit të problemit, ajo ktheu një konflikt "lease currently held" pa që ta provokonim ne, dhe refuzon nisjet ndërsa një makinë po përditësohet.
Rregullimi: vazhdo të kërkosh, dhe trokit në derë
Kontrolli i shëndetit tani:
- kërkon përsëri nisjen e një makine të ndaluar çdo 20 sekonda ndërsa pret,
- regjistron çfarë ktheu platforma kur refuzon, dhe
- i dërgon aplikacionit një kërkesë të zakonshme, ashtu siç do ta bënte një vizitor — proxy i platformës e zgjon makinën në gjumë kur arrin një kërkesë.
E riprodhuam në platformën reale me një aplikacion të përkohshëm, nisja e parë i të cilit u refuzua. Para rregullimit, publikimi dështonte pas 91 sekondash. Pas tij, u publikua në 20 sekonda. Një aplikacion që me të vërtetë rrëzohet kur nis ende dështon, siç duhet.
Çfarë mësuam
- Kthimi mbrapsht duhet ta dijë dallimin mes të resë dhe të ekzistueshmes. "Zhbërja" për diçka që krijove është fshirje. "Zhbërja" për diçka që ishte aty më parë është rikthim. Trajtimi i të dyjave njësoj është mënyra si një mekanizëm sigurie fshin një aplikacion që funksiononte.
- Shkruaje si ta zhbësh para se të veprosh. Nëse zhbërja regjistrohet vetëm pasi një hap ka sukses, një hap që dështon në mes nuk ka çfarë të zhbëjë.
- Mos e injoro kurrë përgjigjen e një kërkese nga e cila varesh. Një "jo" e injoruar e shndërroi një aplikacion të shëndetshëm në një publikim të dështuar.
Një rregullim i lidhur nga e njëjta ditë: rrëzimi i aplikacioneve që bien menjëherë pas publikimit. Për atë që ndodh kur një publikim dështon nga ana jote, shiko zgjidhjen e problemeve me publikimin në dokumentacion.