Săriți la conținut

Blog ·

A proiecta, niciodată a înlocui

O singură vedere de progres peste migrări, copii, restaurări și reinstalări, fără să devină o a doua evidență. Două defecte au fost complet tăcute.

De Provibr

Un panou de găzduire adună muncă de lungă durată. O migrare între două panouri de control, o copie de siguranță, o restaurare într-o mașină nouă, un container care este înlocuit. Fiecare și-a creat tabelul propriu, vocabularul propriu de stări și ecranul propriu, iar asta ține până când cineva pune întrebarea evidentă: ce rulează chiar acum în contul meu și dacă ceva este blocat.

Răspunsul tentant este un sistem de sarcini. Un tabel, o listă de stări, tot restul scrie înăuntru. Răspunsul tentant este și drumul către două surse de adevăr despre același fapt și către o discuție de asistență un an mai târziu, în care sarcina spune eșuat, iar tabelul copiilor spune că arhiva este pe stocare.

De aceea vederea operațiunilor este o proiecție. Citește rândurile existente și scrie deasupra un rezumat. Nu merge niciodată nimic în sens invers: nicio funcție din modulul de oglindire nu atinge rulările de copiere, cele de restaurare, cele de migrare sau reinstalările. Acele tabele rămân adevărul, iar rezumatului i se permite să fie învechit, greșit sau absent fără să se rupă ceva mai departe.

O oglindă per tabel și un test care citește schema

Patru tabele stau pe această cusătură, iar fiecare are exact o funcție care o proiectează.

Tabel sursăColoana de stareTip de operațiune
backup_runsstatusbackup.run
backup_restore_runsstatusbackup.restore
migration_runsstatusmigration.run
container_reinstall_intentsstatecontainer.reinstall

Ultimul rând este motivul pentru care numele coloanelor sunt scrise ca text și nu presupuse. Acel tabel numește coloana state, iar o oglindă care ar citi status nu primește nimic și cade fără să se plângă pe ramura de eșec.

Acel tabel nu este documentație. Un test deduce din schema bazei de date care dintre acele tabele au o coloană de stare, cere o intrare aici pentru fiecare, cere ca funcția numită să existe cu adevărat și cere, iar aceasta este partea care face munca reală, ca fiecare fișier care scrie una dintre acele coloane să își numească și oglinda. Un al cincilea tabel care ajunge pe cusătură fără proiecție este astfel un test roșu în loc de un sertar care încetează în tăcere să se miște.

Atâta severitate este necesară fiindcă scriitorii sunt răspândiți: o rulare de copiere își schimbă starea în șase locuri dintr-un singur fișier, trei dintre ele pe calea care prelucrează răspunsurile reconcilierii care rulează noaptea. A lăsa fiecare scriitor să invoce singur proiecția înseamnă că al șaselea uită, iar uitarea este invizibilă. Rândul este corect. Doar ecranul nu se actualizează niciodată.

Colectorul care exista de două ori

Oglindirea locuiește în pachetul căruia îi aparțin scrierile în baza de date, fiindcă atât o acțiune de server din aplicația web, cât și o componentă a gateway-ului apelează aceleași funcții. Acel pachet nu poate publica un eveniment în direct: depinde de baza de date și de cod comun și de nimic altceva, iar magistrala de mesaje este alt obiect de fiecare parte.

Expune deci un colector. Fiecare aplicație înregistrează unul, iar pachetul nu știe cine l-a completat. Dacă nu o face nimeni, scrierea în baza de date merge oricum mai departe și nu pleacă niciun eveniment în direct, iar sertarul se actualizează la următoarea încărcare de pagină. Este o degradare onestă, iar funcția nu aruncă niciodată intenționat, fiindcă o înregistrare lipsă nu are voie să răstoarne o copie de siguranță.

Colectorul era o variabilă de modul, iar asta era greșit într-un fel care nu producea nicio eroare. Next își rulează fișierul de instrumentare ca pachet propriu, separat de procesele de rută. Variabila exista deci de două ori: înregistrarea ajungea într-un exemplar, iar funcția care emite îl citea pe celălalt. Rândurile erau corecte, stările avansau, sertarul stătea nemișcat și nu exista nicio linie în niciun jurnal.

Asta nu a fost găsit raționând. A fost găsit punând un ascultător pe magistrala de mesaje și numărând: a sosit un eveniment acolo unde trebuiau să fie trei. Reparația este un lăcaș pe globalThis în spatele unui Symbol.for, care supraviețuiește unei granițe de împachetare în același proces, aceeași formă și același motiv ca legătura comună la baza de date și cea la Redis.

Două lecții care valorează mai mult decât defectul. Un defect fără linie de eroare cere un instrument în afara codului bănuit. Iar „acest modul are un exemplar” este o presupunere despre un împachetator, nu o proprietate a limbajului.

Aceeași rundă a găsit un al doilea caz tăcut. Încheierea unei operațiuni și blocarea ei lăsau amândouă coloana de etapă neatinsă, așa că o copie perfect reușită rămânea pentru totdeauna pe „se arhivează”. Nu eșua nimic; doar că ultimul pas nu sosea niciodată.

Anularea este o cerere, iar o singură scriere este dovada

La anulare o proiecție este cel mai tentată să mintă. Sertarul cunoaște operațiunea, operațiunea are un buton de anulare, iar implementarea cea mai ieftină pune un marcaj și închide panoul.

De aceea fiecare tip declară dacă anularea are măcar sens. Un vzdump în curs nu îl putem anula: comanda este la agent, sarcina la hipervizor, iar nimeni nu știe ce reprezintă o jumătate de arhivă pe stocarea clientului. O restaurare este la fel, cu un motiv în plus: rândul de restaurare ține o rezervare pe identificatorul țintă cât timp este deschis, iar închiderea lui devreme eliberează acel identificator în timp ce poate tocmai aterizează un oaspete pe el. Amândouă sunt declarate neacceptate, iar nu există nicio cale care să ocolească asta.

Acolo unde anularea este posibilă, decide tot rândul. O migrare poate fi anulată cât timp este planificată și nu mai poate atunci când un program ajutător scrie servere pe gazda altcuiva. O reinstalare de container poate fi anulată până la previzualizare și nu mai poate după ce agentul a început să înlocuiască.

Când reușește, dovada că nu s-a întâmplat nimic este o singură scriere condiționată: pune comanda din coadă pe anulată acolo unde starea ei este încă în așteptare. Dacă a fost deja trimisă, acea instrucțiune atinge zero rânduri, iar cererea rămâne onest pe „solicitată”. A consulta și apoi a scrie ar fi două instrucțiuni și deci două ocazii de a se strecura ceva între ele.

Și atunci fraza contează. Evenimentul spune că a fost scoasă comanda din coadă înainte ca agentul să o primească, și nu că a fost anulată. Nu s-a întrerupt nimic, fiindcă nu începuse nimic. Acel rând merge în jurnalul general de evenimente și nu în progresul operațiunii, fiindcă progresul este curățat după nouăzeci de zile, iar „un om a intervenit în infrastructură” nu este progres.

Patru blocaje, și niciunul nu este un eșec

Patru situații pun o operațiune pe necesită atenție în loc de eșuată.

Un vzdump a raportat OK, iar arhiva nu este în index. O încercare de copiere și-a depășit timpul, iar noi nu știm dacă arhiva există. O restaurare nu poate fi recitită sau oaspetele rezultat nu a putut fi înregistrat. O reinstalare de container s-a oprit după ce vechiul container dispăruse deja.

A numi eșuată vreuna dintre ele ar fi o minciună cu urmări. Eșuată îl invită pe client să o repete, iar repetarea unei copii înseamnă alte zeci de gigaocteți pe stocarea cuiva pentru o arhivă care poate există deja. Repetarea unei reinstalări înseamnă un al doilea container. Bucla de reconciliere continuă să privească până când indexul se pronunță, iar între timp operațiunea rămâne vizibil blocată, ceea ce este exact doza potrivită de alarmă.

Blocajul poartă și cui îi aparține. Trei dintre ele sunt ale noastre; o comandă care a eșuat cu adevărat de partea clientului spune asta.

O rulare de probă se oprește la planificare, iar asta nu este o lipsă

O migrare de probă are cinci pași; una reală are opt, cei trei în plus fiind scrierea și renumărarea. Lista de etape le conține pe toate șase, deci o probă reușită își arată ultimele două ca nefăcute.

Asta arată ca un defect al unei bare de progres și este adevărul: o probă nu scrie și nu renumără. Alternativele erau un al doilea tip, care dublează nouă intrări de catalog în nouă limbi pentru aceeași muncă, sau o listă de etape care variază de la un rând la altul, ceea ce ar face sertarul și pagina de detaliu să nu mai cadă de acord asupra numărului de pași. Arătarea adevărului a costat mai puțin decât amândouă.

Ce am nota

  1. O proiecție proiectează. Dacă stratul de rezumat poate scrie înapoi în sursă, este o a doua evidență și acum aveți două.
  2. Puneți cusătura într-un tabel pe care un test îl poate citi, derivat din schemă, și puneți-l să verifice că fiecare scriitor al unei coloane de stare își numește oglinda. Un apel uitat nu produce nicio eroare.
  3. Nu presupuneți că un modul are un exemplar. Un cadru care rulează o parte din codul dumneavoastră ca pachet separat vă va da două, iar simptomul este tăcerea.
  4. Măsurați în afara suspectului. Un ascultător pe magistrală a găsit în câteva minute ce citirea nu a găsit deloc.
  5. Spuneți ce s-a întâmplat cu adevărat. „Scoasă din coadă înainte ca agentul să o primească” este mai lung decât „anulată” și este singura variantă exactă.
  6. Rezervați eșuat pentru eșec. Deznodămintele necunoscute au nevoie de o stare proprie, altfel oamenii repetă operațiuni scumpe care poate au reușit deja.

Ca să fie limpede ce este asta: tipurile descrise aici stau în spatele unor comutatoare de lansare oprite implicit, deci migrările și copiile clienților nu se pot cumpăra astăzi. Mai multe lucruri rămân nedovedite. Evenimentul de progres în direct a fost măsurat doar pentru migrări. Partea de gateway a înregistrării colectorului nu a fost pusă la încercare cu un gateway pornit cu adevărat. Lanțul agentului a fost reprodus cu SQL. Iar anularea unei reinstalări de container din ecranul operațiunilor nu a fost niciodată condusă într-un navigator.

Din lucrul de platformă la Provibr. De ce o bară de progres refuză să estimeze o oră de final se află în o bară de progres care refuză să ghicească, iar de ce o migrare care a sărit în tăcere este mai rea decât una eșuată se află în migrarea care nu a rulat niciodată.

Începeți cu o gazdă și un agent

Creați un cont, instalați agentul cu o singură comandă și conectați primul dumneavoastră host Proxmox. Perioada de probă durează 14 zile și nu cere date de plată.