O poveste de lansare care a afectat totul

O poveste de lansare care a afectat totul
Dușmanii Realității prin 12f-2

La sfârșitul lunii aprilie, în timp ce White Walkers asedia Winterfell, ni s-a întâmplat ceva mai interesant; am făcut o lansare neobișnuită. În principiu, lansăm în mod constant noi funcții în producție (ca toți ceilalți). Dar acesta era diferit. Amploarea acesteia a fost de așa natură încât orice potențiale greșeli pe care le-am putea face ar afecta toate serviciile și utilizatorii noștri. Ca urmare, am derulat totul conform planului, în perioada de nefuncționare planificată și anunțată, fără consecințe asupra vânzărilor. Articolul este despre cum am reușit acest lucru și despre cum oricine îl poate repeta acasă.

Nu voi descrie acum deciziile arhitecturale și tehnice pe care le-am luat și nici nu voi spune cum funcționează totul. Acestea sunt mai degrabă note în margine despre cum a avut loc una dintre cele mai dificile lansări, pe care am observat-o și în care am fost direct implicat. Nu pretind completitudine sau detalii tehnice; poate vor apărea într-un alt articol.

Fundal + ce fel de funcționalitate este aceasta?

Construim o platformă cloud Mail.ru Cloud Solutions (MCS), unde lucrez ca director tehnic. Și acum este timpul să adăugăm IAM (Gestionarea identității și accesului) pe platforma noastră, care oferă o gestionare unificată a tuturor conturilor de utilizator, utilizatorilor, parolelor, rolurilor, serviciilor și multe altele. De ce este necesar în cloud este o întrebare evidentă: toate informațiile despre utilizator sunt stocate în el.

De obicei, astfel de lucruri încep să fie construite chiar de la începutul oricărui proiect. Dar din punct de vedere istoric, lucrurile au fost puțin diferite în MCS. MCS a fost construit în două părți:

  • Openstack cu propriul modul de autorizare Keystone,
  • Hotbox (stocare S3) bazat pe proiectul Mail.ru Cloud,

în jurul cărora au apărut apoi noi servicii.

În esență, acestea au fost două tipuri diferite de autorizare. În plus, am folosit câteva dezvoltări separate Mail.ru, de exemplu, o stocare generală a parolei Mail.ru, precum și un conector openid auto-scris, datorită căruia SSO (autorizare end-to-end) a fost furnizată în panoul Horizon de mașini virtuale (interfața de utilizare nativă OpenStack).

A face IAM pentru noi a însemnat să le conectăm pe toate într-un singur sistem, complet al nostru. În același timp, nu vom pierde nicio funcționalitate pe parcurs, ci vom crea o bază pentru viitor care ne va permite să o rafinăm în mod transparent, fără refactorizare și să o scalam din punct de vedere al funcționalității. De asemenea, la început, utilizatorii au avut un model de urmat pentru accesul la servicii (RBAC central, controlul accesului bazat pe rol) și alte câteva lucruri mici.

Sarcina s-a dovedit a fi non-trivială: python și perl, mai multe backend-uri, servicii scrise independent, mai multe echipe de dezvoltare și administratori. Și cel mai important, există mii de utilizatori în direct pe sistemul de producție de luptă. Toate acestea trebuiau scrise și, cel mai important, difuzate fără victime.

Ce vom lansa?

Ca să spunem foarte gros, în aproximativ 4 luni am pregătit următoarele:

  • Am creat mai mulți demoni noi care au agregat funcții care funcționau anterior în diferite părți ale infrastructurii. Restului serviciilor li sa prescris un nou backend sub forma acestor demoni.
  • Am creat propriul nostru stocare central de parole și chei, disponibil pentru toate serviciile noastre, care poate fi modificat în mod liber după cum avem nevoie.
  • Am scris 4 backend-uri noi pentru Keystone de la zero (utilizatori, proiecte, roluri, atribuiri de roluri), care, de fapt, i-au înlocuit baza de date și acum acționează ca un singur depozit pentru parolele utilizatorilor noștri.
  • Am învățat toate serviciile noastre Openstack să meargă la un serviciu de politici terță parte pentru politicile lor, în loc să citim aceste politici local de pe fiecare server (da, așa funcționează Openstack în mod implicit!)

O astfel de reluare majoră necesită schimbări mari, complexe și, cel mai important, sincrone în mai multe sisteme scrise de diferite echipe de dezvoltare. Odată asamblat, întregul sistem ar trebui să funcționeze.

Cum să lansați astfel de modificări și să nu le stricați? Mai întâi ne-am hotărât să privim puțin în viitor.

Strategia de lansare

  • Ar fi posibil să lansați produsul în mai multe etape, dar acest lucru ar crește timpul de dezvoltare de trei ori. În plus, de ceva timp am avea o desincronizare completă a datelor din bazele de date. Ar trebui să vă scrieți propriile instrumente de sincronizare și să trăiți cu mai multe depozite de date pentru o lungă perioadă de timp. Și acest lucru creează o mare varietate de riscuri.
  • Tot ceea ce putea fi pregătit în mod transparent pentru utilizator a fost făcut în avans. A durat 2 luni.
  • Ne-am permis timp de nefuncționare pentru câteva ore - doar pentru operațiunile utilizatorului pentru a crea și a modifica resurse.
  • Pentru funcționarea tuturor resurselor deja create, timpul de nefuncționare a fost inacceptabil. Am planificat ca, în timpul lansării, resursele să funcționeze fără timpi de nefuncționare și să afecteze clienții.
  • Pentru a reduce impactul asupra clienților noștri în cazul în care ceva nu merge bine, am decis să lansăm duminică seara. Mai puțini clienți gestionează mașinile virtuale noaptea.
  • Am avertizat toți clienții noștri că în perioada selectată pentru lansare, managementul serviciilor va fi indisponibil.

Digresiune: ce este o lansare?

<atenție, filozofie>

Fiecare specialist IT poate răspunde cu ușurință ce este o lansare. Instalați CI/CD și totul este livrat automat în magazin. 🙂

Desigur, acest lucru este adevărat. Dar dificultatea este că, cu instrumentele moderne de automatizare a livrării de coduri, înțelegerea lansării în sine este pierdută. Cum uiți de epicitatea invenției roții când te uiți la transportul modern. Totul este atât de automatizat încât lansarea este adesea efectuată fără a înțelege întreaga imagine.

Și întreaga imagine este așa. Lansarea constă din patru aspecte majore:

  1. Livrarea codului, inclusiv modificarea datelor. De exemplu, migrațiile lor.
  2. Derularea codului este abilitatea de a reveni dacă ceva nu merge bine. De exemplu, prin crearea de copii de rezervă.
  3. Ora fiecărei operații de lansare/retroducere. Trebuie să înțelegeți momentul oricărei operațiuni din primele două puncte.
  4. Funcționalitate afectată. Este necesar să se evalueze atât efectele pozitive așteptate, cât și posibilele negative.

Toate aceste aspecte trebuie luate în considerare pentru o lansare reușită. De obicei, este evaluat doar primul punct, sau în cel mai bun caz al doilea, iar apoi lansarea este considerată reușită. Dar al treilea și al patrulea sunt și mai importante. Care utilizator i-ar plăcea dacă lansarea a durat 3 ore în loc de un minut? Sau dacă ceva inutil este afectat în timpul lansării? Sau timpul de nefuncționare al unui serviciu va duce la consecințe imprevizibile?

Act 1..n, pregătire pentru eliberare

La început m-am gândit să descriu pe scurt întâlnirile noastre: întreaga echipă, părțile ei, grămezi de discuții la cafenea, argumente, teste, brainstorm-uri. Atunci m-am gândit că va fi inutil. Patru luni de dezvoltare constau întotdeauna în asta, mai ales când nu scrieți ceva care poate fi livrat în mod constant, ci o caracteristică mare pentru un sistem live. Care afectează toate serviciile, dar nimic nu ar trebui să se schimbe pentru utilizatori, cu excepția „un buton în interfața web”.

Înțelegerea noastră despre cum să lansăm s-a schimbat de la fiecare nouă întâlnire și destul de semnificativ. De exemplu, urma să ne actualizăm întreaga bază de date de facturare. Dar am calculat timpul și am realizat că este imposibil să facem acest lucru într-un timp rezonabil de lansare. Ne-a luat aproape o săptămână în plus pentru a fragmenta și arhiva baza de date de facturare. Și când viteza de lansare așteptată încă nu era satisfăcătoare, am comandat hardware suplimentar, mai puternic, unde întreaga bază a fost târâtă. Nu este că nu am vrut să facem acest lucru mai devreme, dar nevoia actuală de lansare ne-a lăsat fără opțiuni.

Când unul dintre noi a avut îndoieli că lansarea ar putea afecta disponibilitatea mașinilor noastre virtuale, am petrecut o săptămână efectuând teste, experimente, analize de cod și am primit o înțelegere clară că acest lucru nu se va întâmpla în producția noastră și chiar și cei mai îndoielnici au fost de acord. cu asta.

Între timp, băieții de la asistența tehnică și-au efectuat propriile experimente independente pentru a scrie instrucțiuni pentru clienți cu privire la metodele de conectare, care trebuiau să se schimbe după lansare. Au lucrat la UX utilizator, au pregătit instrucțiuni și au oferit consultații personale.

Am automatizat toate operațiunile de lansare posibile. Fiecare operație a fost scriptată, chiar și cele mai simple, iar testele au fost efectuate în mod constant. S-au certat despre cel mai bun mod de a dezactiva serviciul - omiteți demonul sau blocați accesul la serviciu cu un firewall. Am creat o listă de verificare a echipelor pentru fiecare etapă de lansare și am actualizat-o constant. Am desenat și actualizat constant o diagramă Gantt pentru toate lucrările de lansare, cu calendare.

Așadar…

Actul final, înainte de lansare

... este timpul să lansăm.

După cum se spune, o operă de artă nu poate fi finalizată, ci doar terminată de lucrat la ea. Trebuie să faci un efort de voință, înțelegând că nu vei găsi totul, dar crezând că ai făcut toate presupunerile rezonabile, ai asigurat toate cazurile posibile, ai închis toate erorile critice și toți participanții au făcut tot ce au putut. Cu cât lansați mai mult cod, cu atât este mai dificil să vă convingeți de acest lucru (în plus, toată lumea înțelege că este imposibil să prevadă totul).

Am decis că suntem gata să lansăm când am fost convinși că am făcut tot posibilul pentru a acoperi toate riscurile pentru utilizatorii noștri asociate cu afecte neașteptate și timpi de nefuncționare. Adică, orice poate merge prost, cu excepția:

  1. Afectează (sacrată pentru noi, cea mai prețioasă) infrastructura de utilizatori,
  2. Funcționalitate: utilizarea serviciului nostru după lansare ar trebui să fie aceeași ca înainte.

Rulare

O poveste de lansare care a afectat totul
Două aruncări, 8 nu interferează

Luăm timp de nefuncționare pentru toate solicitările de la utilizatori timp de 7 ore. În acest moment, avem atât un plan de lansare, cât și un plan de rollback.

  • Lansarea în sine durează aproximativ 3 ore.
  • 2 ore pentru testare.
  • 2 ore - rezervați pentru o posibilă anulare a modificărilor.

A fost întocmit o diagramă Gantt pentru fiecare acțiune, cât timp durează, ce se întâmplă secvenţial, ce se face în paralel.

O poveste de lansare care a afectat totul
O bucată dintr-o diagramă Gantt de lansare, una dintre versiunile timpurii (fără execuție paralelă). Cel mai valoros instrument de sincronizare

Toți participanții au rolul lor în lansare determinat, ce sarcini fac și de ce sunt responsabili. Încercăm să aducem fiecare etapă la automatizare, să o lansăm, să o rulăm înapoi, să colectăm feedback și să o lansăm din nou.

Cronica evenimentelor

Așadar, 15 persoane au venit la muncă duminică, 29 aprilie, la ora 10. Pe lângă participanții cheie, unii au venit pur și simplu pentru a sprijini echipa, pentru care le mulțumesc în mod special.

De asemenea, merită menționat că testerul nostru cheie este în vacanță. Este imposibil să se lanseze fără testare, explorăm opțiuni. O colegă acceptă să ne testeze din vacanță, pentru care primește o imensă recunoștință din partea întregii echipe.

00:00. Stop
Oprim solicitările utilizatorilor, închidem un panou care spune lucrări tehnice. Monitorizarea țipă, dar totul este normal. Verificăm că nimic nu a căzut în afară de ceea ce trebuia să cadă. Și începem să lucrăm la migrație.

Toată lumea are un plan de lansare tipărit punct cu punct, toată lumea știe cine ce face și în ce moment. După fiecare acțiune, verificăm timpii pentru a ne asigura că nu le depășim și totul decurge conform planului. Cei care nu participă direct la lansare în stadiul actual se pregătesc prin lansarea unei jucării online (Xonotic, șarlatani de tip 3) pentru a nu-și deranja colegii. 🙂

02:00. Rulat
O surpriză plăcută - terminăm lansarea cu o oră mai devreme, datorită optimizării bazelor noastre de date și a scripturilor de migrare. Strigătul general, „rulat!” Toate funcțiile noi sunt în producție, dar până acum doar noi le putem vedea în interfață. Toată lumea intră în modul de testare, îi sortează în grupuri și începe să vadă ce s-a întâmplat în cele din urmă.

Nu a ieșit prea bine, ne dăm seama de asta după 10 minute, când nimic nu este conectat sau lucrează în proiectele membrilor echipei. Sincronizare rapidă, ne exprimăm problemele, ne stabilim priorități, facem echipe și trecem la depanare.

02:30. Două mari probleme vs patru ochi
Găsim două mari probleme. Ne-am dat seama că clienții nu vor vedea unele servicii conectate și că vor apărea probleme cu conturile de parteneri. Ambele se datorează unor scripturi de migrare imperfecte pentru unele cazuri marginale. Trebuie să o reparăm acum.

Scriem interogări care înregistrează acest lucru, cu cel puțin 4 ochi. Le testăm în timpul preproducției pentru a ne asigura că funcționează și că nu sparg nimic. Poți rula mai departe. În același timp, rulăm testarea noastră obișnuită de integrare, care dezvăluie încă câteva probleme. Toate sunt mici, dar trebuie și reparate.

03:00. -2 probleme +2 probleme
Cele două mari probleme anterioare au fost rezolvate și aproape toate cele minore. Toți cei neocupați în corecții lucrează activ în conturile lor și raportează ceea ce găsesc. Prioritizează, distribuim între echipe și lăsăm articole necritice pentru dimineață.

Facem din nou testele, ei descoperă două noi mari probleme. Nu toate politicile de servicii au ajuns corect, așa că unele solicitări ale utilizatorilor nu trec autorizarea. Plus o nouă problemă cu conturile de parteneri. Să ne grăbim să privim.

03:20. Sincronizare de urgență
S-a rezolvat o problemă nouă. Pentru al doilea, organizăm o sincronizare de urgență. Înțelegem ce se întâmplă: remedierea anterioară a remediat o problemă, dar a creat alta. Facem o pauză pentru a ne da seama cum să o facem corect și fără consecințe.

03:30. Șase ochi
Înțelegem care ar trebui să fie starea finală a bazei, astfel încât totul să meargă bine pentru toți partenerii. Scriem o cerere cu 6 ochi, o lansăm în pre-producție, o testăm, o lansăm pentru producție.

04:00. Totul merge
Toate testele au trecut, nu sunt vizibile probleme critice. Din când în când, ceva în echipă nu funcționează pentru cineva, reacționăm prompt. Cel mai adesea alarma este falsă. Dar uneori ceva nu ajunge sau o pagină separată nu funcționează. Stăm, reparăm, reparăm, reparăm. O echipă separată lansează ultima mare caracteristică - facturarea.

04:30. Punct fără întoarcere
Se apropie punctul de nereturnare, adică momentul în care, dacă începem să revenim, nu vom mai îndeplini timpul de nefuncționare care ni s-a dat. Sunt probleme cu facturarea, care știe și înregistrează totul, dar refuză cu încăpățânare să scoată banii de la clienți. Există mai multe erori pe pagini individuale, acțiuni și stări. Funcționalitatea principală funcționează, toate testele trec cu succes. Decidem că lansarea a avut loc, nu vom derula înapoi.

06:00. Deschis pentru toată lumea din interfața de utilizare
Erori remediate. Unele care nu atrag utilizatorii sunt lăsate pentru mai târziu. Deschidem interfața tuturor. Continuăm să lucrăm la facturare, așteptând feedbackul utilizatorilor și rezultatele monitorizării.

07:00. Probleme cu încărcarea API-ului
Devine clar că am planificat ușor greșit încărcarea pe API-ul nostru și am testat această încărcare, care nu a putut identifica problema. Ca rezultat, ≈5% dintre solicitări eșuează. Să ne mobilizăm și să căutăm motivul.

Facturarea este încăpățânată și nici nu vrea să funcționeze. Hotărâm să o amânăm pentru mai târziu pentru a efectua schimbările într-o manieră calmă. Adică, toate resursele sunt acumulate în el, dar ștergerile de la clienți nu trec. Desigur, aceasta este o problemă, dar în comparație cu lansarea generală pare lipsită de importanță.

08:00. Remediați API-ul
Am lansat o remediere pentru încărcătură, eșecurile au dispărut. Începem să mergem acasă.

10:00. Toate
Totul este reparat. Este liniște în monitorizare și la locul clienților, echipa se duce treptat la culcare. Facturarea rămâne, o vom restabili mâine.

Apoi, în timpul zilei, au existat lansări care au remediat jurnalele, notificările, codurile de returnare și personalizările pentru unii dintre clienții noștri.

Deci, lansarea a avut succes! Ar putea fi, desigur, mai bine, dar am tras concluzii despre ceea ce nu ne-a fost suficient pentru a ajunge la perfecțiune.

În total

Pe parcursul a 2 luni de pregătire activă pentru lansare, au fost finalizate 43 de sarcini, cu o durată de la câteva ore până la câteva zile.

În timpul lansării:

  • demoni noi și schimbați - 5 bucăți, înlocuind 2 monoliți;
  • modificări în bazele de date - toate cele 6 baze de date noastre cu date de utilizator au fost afectate, s-au făcut descărcări din trei baze de date vechi într-una nouă;
  • frontend complet reproiectat;
  • cantitatea de cod descărcat - 33 mii de linii de cod nou, ≈ 3 mii de linii de cod în teste, ≈ 5 mii de linii de cod de migrare;
  • toate datele sunt intacte, nicio mașină virtuală a unui client nu a fost deteriorată. 🙂

Bune practici pentru o bună lansare

Ei ne-au îndrumat în această situație dificilă. Dar, în general, este util să le urmăriți în timpul oricărei lansări. Dar cu cât lansarea este mai complexă, cu atât rolul pe care îl joacă este mai mare.

  1. Primul lucru pe care trebuie să-l faceți este să înțelegeți modul în care lansarea poate sau va afecta utilizatorii. Va fi timp de nefuncționare? Dacă da, care este timpul de nefuncționare? Cum va afecta acest lucru utilizatorii? Care sunt cele mai bune și cele mai rele scenarii posibile? Și acoperiți riscurile.
  2. Planifică totul. În fiecare etapă, trebuie să înțelegeți toate aspectele lansării:
    • livrarea codului;
    • rollback cod;
    • timpul fiecărei operații;
    • funcționalitatea afectată.
  3. Jucați prin scenarii până când toate etapele lansării, precum și riscurile la fiecare dintre ele, devin evidente. Dacă aveți îndoieli, puteți face o pauză și puteți examina separat etapa discutabilă.
  4. Fiecare etapă poate și ar trebui îmbunătățită dacă îi ajută pe utilizatorii noștri. De exemplu, va reduce timpul de nefuncționare sau va elimina unele riscuri.
  5. Testarea rollback-ului este mult mai importantă decât testarea livrării codului. Este necesar să verificați dacă, ca urmare a derulării înapoi, sistemul va reveni la starea inițială și confirmați acest lucru cu teste.
  6. Tot ceea ce poate fi automatizat ar trebui să fie automatizat. Tot ceea ce nu poate fi automatizat ar trebui să fie scris în prealabil pe o foaie de cheat.
  7. Înregistrați criteriul de succes. Ce funcționalități ar trebui să fie disponibile și la ce oră? Dacă acest lucru nu se întâmplă, rulați un plan de rollback.
  8. Și cel mai important - oameni. Toată lumea ar trebui să fie conștientă de ceea ce face, de ce și ce depinde de acțiunile lor în procesul de lansare.

Și într-o singură propoziție, cu o bună planificare și elaborare, puteți rula orice doriți fără consecințe pentru vânzări. Chiar și ceva care vă va afecta toate serviciile în producție.

Sursa: www.habr.com

Adauga un comentariu