Un clic, apoi liniște

Înregistrarea a trecut deja de verificare. Referința furnizorului, suma și documentul justificativ se văd lângă un semn verde de aprobare. Operatorul apasă „Trimite” și așteaptă. Un indicator se învârte. Apoi interfața spune că cererea a eșuat.

Ce a eșuat e conversația dintre două servicii. Acțiunea de afaceri poate să fi reușit. Distincția aceasta lipsește de pe ecran, iar operatorului i se cere să ia o decizie fără ea.

Un al doilea clic e de înțeles. Dacă aplicația îi dă reîncercării o identitate nouă, serviciul care o primește o poate înțelege ca pe o a doua înregistrare intenționată. Duplicatul începe ca o problemă de design înainte să devină o problemă de contabilitate.

Păstrați același identificator la reîncercare

Prima reparație este să dați operațiunii de afaceri intenționate o identitate stabilă, păstrată de la o încercare de transport la alta. Relatarea Amazon despre API-urile idempotente explică cum un identificator trimis de client îi poate permite unui serviciu să recunoască o reîncercare. API-ul care primește cererea trebuie să ofere cu adevărat acest contract; un câmp aleatoriu adăugat la o cerere nu creează nicio garanție.

În integrarea imaginată de noi, al doilea clic al operatorului ar trebui să reia operațiunea inițială. O factură modificată e altceva. Sistemul are nevoie de o regulă de corectare care să deosebească reîncercarea aceleiași intenții de autorizarea uneia noi.

Sistemul trebuie să poată gestiona și un rezultat necunoscut

Acum schimbați ecranul. Spune că trimiterea a fost încercată și că lipsește confirmarea. Arată referința de afaceri și oferă următoarea acțiune sigură: verificarea destinației după acea referință. Nu îl invită pe operator să creeze o înregistrare nouă.

Lucrarea lui Pat Helland despre viața dincolo de tranzacțiile distribuite discută tipare de aplicație pentru coordonarea muncii între entități gestionate separat. Legătura practică de aici este responsabilitatea pentru progresul parțial. Dacă integrarea nu are o tranzacție comună pentru ambele servicii, fluxul ei de lucru trebuie să țină cont de intervalul în care ele nu sunt de acord sau nu pot comunica.

Aplicația poate ține minte acest interval. Pregătit, trimis, confirmat și incert sunt stări diferite. Fiecare merită altă acțiune de recuperare.

Stare cunoscutăUrmătoarea acțiune utilă
PregătitTrimiteți sub identitatea stabilă a operațiunii
Trimis, fără confirmareReconciliați cu destinația
ConfirmatAfișați referința de la destinație
Respins la validareCorectați cauza înainte de o nouă încercare

Operatorul deschide înregistrarea

Înregistrarea conține un identificator al operațiunii, momentul încercării, destinația și ultimul rezultat confirmat. Trimite la datele de intrare verificate fără să copieze conținut privat inutil în fiecare jurnal. Operatorul vede destul cât să stabilească starea operațiunii.

Ghidul SRE al Google despre monitorizare separă semnalele operaționale utile de un potop de date fără direcție. Pentru acest flux de lucru, am face vizibile operațiunile nerezolvate sub forma unei cozi cu un responsabil. Un serviciu poate răspunde cu succes la verificările de sănătate în timp ce coada de muncă incertă continuă să crească.

Dacă destinația confirmă acceptarea, actualizați înregistrarea locală. Dacă confirmă respingerea, corectați eroarea. Dacă nu puteți afla rezultatul și nici repeta cererea în siguranță, trimiteți cazul unei persoane care îl poate verifica.

Testați lipsa confirmării

Înainte să lansați integrarea, întrerupeți-o după ce destinația acceptă o cerere și înainte ca apelantul să primească confirmarea. Apoi rugați pe cineva care nu a construit-o să recupereze operațiunea. Urmăriți starea operațiunii în sistemul destinație, nu doar jurnalele apelantului.

Repetați cu un eveniment duplicat și cu o factură corectată. Aceeași identitate ar trebui să păstreze aceeași intenție, conform comportamentului documentat al API-ului; o corectură ar trebui să urmeze regula de afaceri convenită. Contractul de idempotență are nevoie de aceste detalii ca să fie util.

Incidentul se încheie bine când operatorul poate spune ce s-a întâmplat, poate arăta dovezile și poate relua munca fără să creeze un al doilea efect. Aceasta este funcția care îi lipsea integrării.

Dacă lipsește confirmarea, verificați dacă operațiunea a fost executată înainte să o repetați.

Surse și lecturi suplimentare

  1. Amazon Builders’ Library — Making retries safe with idempotent APIs
  2. Helland — Life beyond Distributed Transactions: an Apostate’s Opinion (CIDR 2007)
  3. Google SRE — Monitoring Distributed Systems

Sursele citate susțin explicațiile tehnice. Exemplele și metodele propuse sunt ale MGLO, iar scenariile ilustrative sunt marcate în text.