Sags pattern e transazioni distribuite
Pattern saga e transazioni distribuite
1) Perché hai bisogno di saghe
La classica 2PC (bidirezione) non è scalabile, complessa sotto i guasti e blocca le risorse. La saga suddivide il processo aziendale generale in una sequenza di transazioni locali (step), ciascuna delle quali viene gestita in modo indipendente. In caso di errore, i passaggi successivi vengono annullati e quelli già completati vengono compensati con le operazioni invertite.
Risultato: gestione eventual consistency senza blocco globale, elevata vitalità e protocollo di ripristino chiaro.
2) Modelli di base
2. 1 Orchestrazione
Il coordinatore della saga selezionato gestisce i passaggi: invia comandi, attende risposte/eventi e avvia i compensi.
I vantaggi sono il controllo centralizzato, la semplice osservabilità, le deadline evidenti. Meno - Componente aggiuntivo.
2. 2 Coreografia
Nessun coordinatore; i servizi rispondono agli eventi reciproci (« », « »...).
I vantaggi sono una scarsa connettività. Contro, più difficile da rintracciare, il rischio dì ballo della morte "senza regole chiare.
2. 3 TCC (Try-Confirm/Cancel)
Opzione di congelamento delle risorse:1. Try - preparazione/riserva,
2. Confirm - Fissazione,
3. Cancel - Reimpostazione.
Le garanzie sono più alte, ma i contratti e i timeout delle riserve sono più difficili.
3) Contratti di passo e compensazione
Ogni passaggio = transazione locale + compensazione (idipotente, ripetizione).
La compensazione non è obbligata a «restituire il mondo» - sufficiente equivalenza di dominio (ad esempio, «rimborso rimborso» anziché «cancellare il pagamento»).
Definire gli invarianti: per i soldi, il saldo non va in svantaggio; Nessun stato dipendente per gli ordini.
Immettere deadline/TTL di riserva e «garbage detector» per tentativi scaduti.
4) Coerenza e semantici di consegna
Consegna messaggi: at-least-once (default), tutte le operazioni devono essere idipotenti.
Ordine: importante per la chiave di correlazione (ad esempio, «order _ id», «player _ id»).
Exactly-once non è l'obiettivo della saga; raggiungiamo l'efficacia di una sola volta attraverso chiavi idempotate, outbox/inbox e la corretta committenza.
5) Stato della saga e il suo login
Cosa conservare:- «saga _ id», «correlation _ id», stato corrente (Running/Completed/Componating/Componated/Failed),
- passo e le sue variabili (IDS pagamenti/riserve),
- cronologia (registro) eventi/soluzioni, timeline, deadline, numero di retrai.
- Un singolo Saga Store (tabella/documento) disponibile per il coordinatore.
- Per la coreografia, gli agenti locali della saga che pubblicano eventi di stato in un topic comune.
6) Pattern di pubblicazione affidabile: outbox/inbox
Outbox: la fase Commit modifica e registra l'evento/comando nella tabella outbox in una singola transazione; Il worker sta pubblicando nella gomma.
Inbox: il consumatore mantiene una tabella di elaborati'messaggio _ id ', elaborato'.
Dopo il successo dell'effetto collaterale, il committente offset/ACK (Kafka/RabbitMQ) non prima.
7) Progettazione dei passi della saga
7. 1 Esempio (acquisto in iGaming/e-commerce)
1. lo stato «PENDING».
2. AuthorizePayment (Try) → `payment_hold_id`.
3. ReserveInventory → `reservation_id`.
4. CapturePayment (Confirm).
5. FinalizeOrder → `COMPLETED`.
- Se (3) ha fallito « »;
- se (4) ha fallito dopo (3) « »;
- Se (5) è fallito « » e « ».
7. 2 Deadline/retrai
Massimo N retrai con ritardo esponenziale + jitter.
Dopo il superamento, passa a Compensating.
Memorizza next _ attempt _ at e deadline _ at per ogni passo.
8) Piattaforma orchestratore vs
Opzioni:- Orchestratore di casa leggero (microservice + tabella Saga).
- Le piattaforme Temporal/Cadence, Camunta, Netflix Conduttore, Zeebe forniscono timer, retrai, workflow a lunga vita, visibilità e console web.
- Per la coreografia, utilizzare una directory di eventi e un contratto di stato/chiave rigoroso.
9) Protocolli di integrazione
9. 1 Asincrono (Kafka/RabbitMQ)
Comandi dì payments ". authorize. v1`, `inventory. reserve. v1`.
Eventi dì payments ". authorized. v1`, `inventory. reserved. v1`, `payments. captured. v1`, `payments. refunded. v1`.
Chiave partitura = «order _ id »/« player _ id» per l'ordine.
9. 2 Sincrono (HTTP/gRPC) all'interno del passo
È accettabile per i passaggi «brevi», ma sempre con timeout/retrai/idipotenza e fallback in compensazione asincrona.
10) Idempotenza e chiavi
Nelle richieste di rimborso e comando, trasmettere «idempotency _ key».
Gli effetti collaterali (scrittura nel database/riscossione) vengono eseguiti in libertà vigilata: «esegui se non hai ancora visto» idempotency _ key «».
Anche i risarcimenti sono idipotenti: la ripetizione dì RefundPayment (id = X) "è sicura.
11) Gestione degli errori
Classi:- Transit (reti/timeout) → retrai/backoff.
- Business (fondi insufficienti, limiti) → un risarcimento immediato/un percorso alternativo.
- Irrecoverable (violazione dell'invariante), intervento manuale, risarcimento manuale.
- Creare una matrice di soluzioni: tipo di errore di azione (retry/compensate/escalate).
12) Osservabilità e SLO
SLI/SLO:- End-to-end latency saga (p50/p95/p99).
- Success rate (percentuale completata senza rimborso).
- Mean time to compensate и compensation rate.
- Orphaned sagas (appesi) e tempo prima di GC.
- Traccia «trace _ id »/« saga _ id» come span link tra i passi; metriche di burn-rate per il bilancio degli errori.
Loghi: ogni cambio di stato della saga = scrittura strutturata con causa.
13) Esempi (pseudocode)
13. 1 Orchestratore (idea)
python def handle(OrderPlaced e):
saga = Saga. start(e. order_id)
saga. run(step=authorize_payment, compensate=cancel_payment)
saga. run(step=reserve_inventory, compensate=release_inventory)
saga. run(step=capture_payment, compensate=refund_payment)
saga. run(step=finalize_order, compensate=refund_and_release)
saga. complete()
def run(step, compensate):
try:
step () # local transaction + outbox except Transient:
schedule_retry()
except Business as err:
start_compensation(err)
13. 2 Outbox (idea di tabella)
outbox(id PK, aggregate_id, event_type, payload, created_at, sent_at NULL)
inbox(message_id PK, processed_at, status)
saga(order_id PK, state, step, next_attempt_at, deadline_at, context JSONB)
saga_log(id PK, order_id, time, event, details)
13. 3 Coreografia (idee di temi)
`orders. placed'consumatori: 'payments. authorize`, `inventory. reserve`
`payments. authorized` + `inventory. reserved` → `orders. try_finalize`
Qualsiasi rifiuto degli orders. compensate' → sono iniziati 'payments. cancel/refund`, `inventory. release`.
14) Confronto con 2PC e ES
2PC: forte coerenza, ma blocchi, colli di bottiglia, tubi di rame.
Saga eventual consistency, serve una disciplina dei compensi e della telemetria.
Event Source: memorizza gli eventi come fonte di verità; le saghe sono naturali, ma aggiungono la complessità delle migrazioni/snapshot.
15) Sicurezza e compliance
Sicurezza dei trasporti (TLS/mTLS), ACL per topic/queue.
In eventi - PI minimo, crittografia dei campi sensibili, tornizzazione.
Controllo dell'accesso alle saghe e ai registri dei compensi.
SLA con provider esterni (pagamenti/consegne) = opzioni di deadline e limiti di retro.
16) Assegno foglio di implementazione (0-45 giorni)
0-10 giorni
Selezionare i processi candidati (multiservizi, con compensazione).
Selezionate un modello (orchestrazione/coreografia/TSS) e una chiave di correlazione.
Descrivere i passi/risarcimenti, invarianti e deadline. Alzare le tabelle «saga», «outbox», «inbox».
11-25 giorni
Abilita outbox/inbox, idampotenza e retrai con backoff.
Deponete le prime sagre; aggiungete i dashboard SLI/SLO e il tracciamento.
Scrivi il runbook dei compensi (ad esempio manuali) e delle escalation.
26-45 giorni
Automatizzare le saghe GC «appese», riavviare/continuare periodicamente la deadline.
Eseguire il game-day: interruzione del passo, superamento della deadline, indisponibilità del broker.
Standardizzare i contratti di eventi (versioni, compatibilità) e creare un catalogo di saghe.
17) Anti-pattern
«Compensazione = delete da database» invece di un'azione inversa di dominio corretta.
Nessun outbox/inbox. Perdita di eventi/doppi effetti.
I retrai senza jitter hanno → le dipendenze da solo-DDoS.
Attendere una forte coerenza nella lettura senza «in corso di elaborazione»....
Un gigantesco orchestratore per tutti i monoliti di controllo.
Coreografia totale senza visibilità e SLA → una danza fuori controllo.
Ignorando le deadline, ci sono riserve e/colline eterne.
18) Metriche di maturità
il 90% dei processi critici sono coperti da saghe/compensi e hanno gli invarianti descritti.
Outbox/inbox sono integrati per tutti i costruttori/consumatori Tier-0/1.
SLO: p95 end-to-end saga normale, success rate stabile, orphaned <target.
Tracciabilità trasparente e dashboard «passo», burn-rate alert.
Game-day trimestrale e controllo dei compensi runbook manuali.
19) Conclusione
La saga è un contratto pratico di coerenza per i sistemi distribuiti: passo chiaro e azione inversa, disciplina di pubblicazione (outbox/inbox), deadline e retrai, osservabilità e processi di compensazione. Scegli un modello (orchestrazione/coreografia/TSS), fissi gli invarianti e le chiavi, rendi idipotenti i processori e i processi aziendali multi-iservizi diventano prevedibili e sostenibili senza un 2PC costoso.