Blog

Un republish eșuat nu șterge niciodată un backend funcțional

Pe 25 septembrie, un republish eșuat a șters backend-ul unei aplicații care fusese live și funcțional timp de aproximativ două ore și jumătate. Codul care anulează o publicare eșuată a eliminat fiecare aplicație de server atinsă de publicare, inclusiv cele care serveau deja înainte să înceapă. Acum, doar aplicațiile create de o publicare sunt șterse vreodată; o aplicație care exista deja este readusă exact la versiunea pe care o rula înainte. Două corecturi ulterioare, în aceeași zi, au asigurat că anularea rulează și atunci când instrumentul de deploy al platformei de hosting eșuează și că o aplicație sănătoasă nu este marcată drept eșuată doar pentru că dormea.

Cum este publicat un backend

Când aplicația ta Mythex are un backend, adică un API sau un server, nu doar fișiere statice, publicarea îl construiește dintr-un Dockerfile (o rețetă de împachetare a aplicației într-o imagine) și lansează acea imagine pe mașinile platformei noastre de hosting. Apoi, un health check așteaptă ca noua versiune să pornească efectiv și să rămână în funcțiune înainte ca publicarea să fie marcată ca live.

Dacă ceva eșuează pe parcurs, rulează un rollback care anulează totul. Rollback-ul trebuie făcut corect mai mult decât aproape orice altceva din publicare, pentru că rulează exact atunci când ceva merge deja prost.

Problema 1: rollback-ul ștergea ce trebuia să restaureze

Rollback-ul ținea o listă cu aplicațiile de server pe care le implementase o publicare și, la eșec, le distrugea pe toate. Asta este corect pentru o primă publicare: aplicația tocmai a fost creată, nimic nu depinde de ea, iar ștergerea o lasă cum era înainte.

Pentru un republish este exact greșit. Aplicația exista deja și servea vizitatori reali. Pe 25 septembrie, API-ul unei aplicații care fusese live timp de aproximativ două ore și jumătate a fost șters de un republish eșuat.

În același cod exista și un al doilea defect. Acolo unde ștergerea nu reușea, noua imagine defectă rămânea pe mașini, în timp ce îi spuneam proprietarului că site-ul actual este încă live. Până când health check-ul poate eșua, noua imagine a fost deja distribuită pe fiecare mașină. A nu face nimic nu înseamnă a anula.

Soluția: distrugi doar ce ai creat, restaurezi restul

Fiecare publicare înregistrează acum, pentru fiecare aplicație de server pe care o atinge:

  • dacă această publicare a creat-o, și
  • dacă nu, ce imagine rula chiar înainte.

La eșec, fiecare aplicație primește unul dintre trei tratamente:

  1. Creată de această publicare: o distrugem, ca înainte.
  2. Exista deja, imaginea anterioară este cunoscută: redeploy-ăm imaginea anterioară cu aceeași configurație. Fără build; doar imaginea se întoarce.
  3. Exista deja, imaginea anterioară este necunoscută: o lăsăm neatinsă. O aplicație existentă nu este ștearsă niciodată, chiar dacă nu o putem restaura.

Aceste reguli sunt o mică funcție pură, cu propriile teste, astfel încât decizia nu poate reveni la „distrugem tot” fără ca un test să pice.

Problema 2: instrumentul de deploy putea eșua înainte să notăm cum se anulează

Puțin după această corectură, am găsit o lacună în ea. Instrumentul de deploy al platformei de hosting rulează propriile verificări de fum: dacă noile mașini se blochează, iese cu o eroare. Dar face asta după ce noua imagine este deja pe mașini.

Codul nostru înregistra o aplicație pentru rollback abia după ce instrumentul returna succes. Când instrumentul însuși eșua deploy-ul, aplicația nu era încă pe lista de rollback, deci nimic nu era restaurat. În mediul nostru de staging, un republish defect a lăsat în funcțiune imaginea defectă.

Soluția: înregistrezi anularea înainte să începi

Aplicația este acum înregistrată pentru rollback, cu informația dacă a fost creată și ce imagine rula, imediat ce este pregătită și înainte ca ceva să fie distribuit pe ea. Oricare ar fi pasul care eșuează după aceea, rollback-ul știe ce trebuie să pună înapoi. Am verificat local: un republish defect a eșuat în verificările de fum ale instrumentului de deploy, iar versiunea anterioară a continuat să răspundă.

Problema 3: o aplicație care dormea a fost marcată drept „nu a pornit niciodată”

Aplicațiile publicate pe Mythex intră în repaus când sunt inactive, ca să economisească din creditele tale. Un republish lasă o mașină oprită, deci health check-ul trebuie să o trezească. Cerea platformei să pornească mașina o singură dată și ignora răspunsul.

Pe 25 septembrie, această unică cerere de pornire nu a ajuns nicăieri. Un API sănătos a rămas oprit pe toată durata health check-ului de cinci minute și a fost marcat drept eșuat cu „1 machine never started (last state: stopped)”.

Platforma refuză uneori o pornire. În timp ce reproduceam problema, a returnat un conflict „lease currently held” fără să-l provocăm noi, iar refuză pornirile cât timp o mașină este actualizată.

Soluția: continui să ceri și bați la ușă

Health check-ul face acum următoarele:

  • cere din nou pornirea unei mașini oprite la fiecare 20 de secunde cât așteaptă,
  • înregistrează ce a răspuns platforma când refuză, și
  • trimite o cerere obișnuită către aplicație, așa cum ar face un vizitator. Proxy-ul platformei trezește o mașină adormită atunci când sosește o cerere.

Am reprodus problema pe platforma reală, cu o aplicație de probă a cărei primă pornire a fost refuzată. Înainte de corectură, publicarea a eșuat după 91 de secunde. După, a fost publicată în 20 de secunde. O aplicație care chiar se blochează la pornire tot eșuează, cum ar trebui.

Ce am învățat din asta

  • Rollback-ul trebuie să știe diferența dintre nou și existent. „Anulare” pentru ceva ce ai creat înseamnă ștergere. „Anulare” pentru ceva care era deja acolo înseamnă restaurare. Tratarea lor la fel este modul în care un mecanism de siguranță șterge o aplicație funcțională.
  • Notează cum se anulează înainte să acționezi. Dacă anularea este înregistrată abia după ce un pas reușește, un pas care eșuează la mijloc nu lasă nimic cu ce să anulezi.
  • Nu ignora niciodată răspunsul la o cerere de care depinzi. Un „nu” ignorat a transformat o aplicație sănătoasă într-o publicare eșuată.

O corectură legată, din aceeași zi: detectarea aplicațiilor care se blochează imediat după publicare. Pentru ce se întâmplă când o publicare eșuează din partea ta, vezi depanarea publicării din documentație.

Mythex · Pricing · Construiește orice cu AI · Șabloane pentru site-uri și aplicații · Mythex comparat · Glosar pentru crearea de aplicații cu AI · Instrumente gratuite pentru crearea de aplicații cu 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) Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)