Sags Pattern e transações distribuídas
Saga-pattern e transações distribuídas
1) Para quê são as sagas
O clássico 2PC (fixação de dois fases) é mal escalado, dobrado sob falhas e bloqueia recursos. A saga divide o processo geral de negócios em uma sequência de transações (passos) locais, cada uma delas de forma independente. Os passos subsequentes são cancelados e os passos já concluídos são compensados por transações revertidas.
Resultado: consistency evolutiva administrada sem bloqueio global, alta vitalidade e protocolo de recuperação claro.
2) Modelos básicos
2. 1 Orquestra
O coordenador da saga selecionado controla os passos: envia comandos, espera por respostas/eventos e inicia compensações.
Os benefícios são controle centralizado, observabilidade simples, deadline aparentes. Contras: componente extra.
2. 2 Coreografias
Sem coordenador; os serviços respondem aos acontecimentos um do outro (« » « »...).
Os benefícios são uma conectividade fraca. Contras: mais difícil de rastrear, risco de «dança da morte» sem regras claras.
2. 3 TCC (Try-Confirm/Cancel)
Opção de congelamento de recursos:1. Try - preparação/reserva,
2. Confirm - fixação,
3. Cancel é um retrocesso.
As garantias são mais altas, mas os contratos e os temporizadores das reservas são mais difíceis.
3) Contratos de passos e compensações
Cada etapa = transação local + compensação (idumpotente, permite repetição).
A compensação não é totalmente obrigada a «recuperar o mundo» - equivalência de domínio suficiente (por exemplo, «reembolso» em vez de «remover o pagamento»).
Defina os invariantes: para o dinheiro, o saldo não vai para menos; para pedidos - não há estatais «dependentes».
Insira deadline/TTL de reservas e «garbage captor» para tentativas vencidas.
4) Coerência e semânticos de entrega
Entrega de mensagens: at-least-once (default) → todas as transações devem ser idimpotentes.
Ordem: Importante por chave de correlação (por exemplo, 'order _ id', 'player _ id').
Exactly-once não é o objetivo da saga; Obtemos efetivamente exatamente uma única vez através de chaves idumpotentes, outbox/inbox e conveniência correta.
5) O estado da saga e seu logo
O que guardar:- 'saga _ id', 'correlation _ id', status atual (Running/Completed/Compensating/Compensated/Failed),
- passo e suas variáveis (IDs pagamentos/reservas),
- histórico de eventos/decisões, temporizadores, deadline, número de retrações.
- Uma Saga Store separada (tabela/documento) disponível para o coordenador.
- Para a coreografia, os «agentes» locais da saga publicam eventos de status em um top comum.
6) Pattern de publicação confiável: outbox/inbox
Outbox: passo comutando alterações e gravando evento/comando em uma tabela de outbox em uma transação; O worker publica no pneu.
Inbox: O consumidor mantém a tabela de 'mensagem _ id' processada → dedupo + idempotidade.
Depois de um efeito colateral bem-sucedido, o offset/ACK (Kafka/RabbitMQ) não é antes.
7) Projetar os passos da saga
7. 1 Exemplo (compra em iGaming/e-commerce)
1. PlaceOrder → status 'PENDING'.
2. AuthorizePayment (Try) → `payment_hold_id`.
3. ReserveInventory → `reservation_id`.
4. CapturePayment (Confirm).
5. FinalizeOrder → `COMPLETED`.
- Se (3) falhou o → 'CancelPaymentHold';
- se (4) falhou após (3) → 'ReleaseInventory';
- Se (5) falhar « » e « ».
7. 2 Deadline/retrai
Máximo N retraes com atraso exponencial + jitter.
Depois de ultrapassado, vai para «Compensating».
Guarde next _ attempt _ at e deadline _ at para cada passo.
8) Plataforma orquestrador vs
Opções:- Orquestrador doméstico leve (microsserviço + tabela Saga).
- Plataformas: Temporal/Cadence, Camunda, Netflix Condutor, Zeebe - fornecem temporizadores, retais, workflow longa vida, visibilidade e console Web.
- Use um catálogo de eventos e um acordo rigoroso de status/chave para a coreografia.
9) Protocolos de integração
9. 1 Asincrona (Kafka/RabbitMQ)
Comandos: 'payments. authorize. v1`, `inventory. reserve. v1`.
Eventos: 'payments. authorized. v1`, `inventory. reserved. v1`, `payments. captured. v1`, `payments. refunded. v1`.
Chave de partição = 'order _ id '/' player _ id' para ordem.
9. 2 Sincronizado (HTTP/gRPC) dentro do passo
É aceitável para passos «curtos», mas sempre com timouts/retais/idumpotência e fallback para compensação asincrônica.
10) Idempotidade e chaves
Nas solicitações de comandos e compensações, envie 'idempotency _ key'.
Os efeitos secundários (gravação em BB/cancelamento) são executados em condicional: «Se ainda não for visto 'idempotency _ key'».
As compensações também são idimpotentes: a repetição 'RefundPayment (id = X)' é segura.
11) Processamento de erros
Classes:- Transient (redes/temporizadores) → retraí/backoff.
- Business (fundos insuficientes, limites) → compensação imediata/via alternativa.
- Irrecoverable (violação do invariante) → intervenção manual, compensação manual.
- Construa a matriz de soluções: tipo de erro → ação (retry/compensate/escalate).
12) Observabilidade e sagas SLO
SLI/SLO:- End-to-end latency saga (p50/p95/p99).
- Sucess rate (proporção de concluídos sem compensação).
- Mean time to compensate и compensation rate.
- Orphaned sagas (pendurados) e tempo para GC.
- Traçado: 'trace _ id '/' saga _ id' como span link entre os passos; métricas burn-rate para os orçamentos de erros.
Logi: cada mudança de status da saga = gravação estruturada com causa.
13) Exemplos (pseudocode)
13. 1 Orquestrador (ideia)
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 (ideia de tabela)
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 (ideias de temas)
`orders. placed '→ consumidores: ' payments. authorize`, `inventory. reserve`
`payments. authorized` + `inventory. reserved` → `orders. try_finalize`
Qualquer falha → 'orders. compensate '→ são iniciados' payments. cancel/refund`, `inventory. release`.
14) Comparação com 2PC e ES
2PC: forte coerência, mas bloqueios, estreitos, «tubos de cobre».
A saga eventual consistency, precisa de disciplina de compensação e telemetria.
Event Surcing: armazena eventos como fonte da verdade; as sagas nele são naturais, mas adicionam a complexidade das migrações/snapshots.
15) Segurança e Complacência
Segurança de transporte (TLS/mTLS), LCA per topic/queue.
Os eventos incluem PII mínimo, criptografia de campos sensíveis, toquenização.
Auditoria de acesso a sagas e registros de compensação.
SLA com provedores externos (pagamentos/entregas) = parâmetros de deadline e limites de retais.
16) Folha de cheque de implementação (0-45 dias)
0-10 dias
Selecione os processos candidatos (multifacetados, compensados).
Selecione um modelo (orquestra/coreografia/TSS) e uma chave de correlação.
Descreva os passos/compensações, invariantes e dedline. Alça as tabelas «saga», «outbox», «inbox».
11 a 25 dias
Inclua outbox/inbox, idempotidade e retraí com backoff.
Deploie as primeiras sagas; adicione dashboards SLI/SLO e rastreamento.
Escreva as compensações de runbook (incluindo manuais) e escaladas.
26-45 dias
Automatize as sagas GC penduradas, reiniciando/continuando periodicamente.
Execute o game-day: falha no passo, excesso de deadline, indisponibilidade do corretor.
Normalize os contratos de eventos (versões, compatibilidade) e estabeleça um diretório de sagas.
17) Anti-pattern
«Compensação = delete da base de dados» em vez de inversão de domínio correto.
Nenhum outbox/inbox → perda de eventos/duplos efeitos.
Retraias sem jitter → dependências si-DDoS.
Espera uma forte coerência na leitura sem «processamento em curso»....
Um orquestrador gigante para todos os monólitos de controlo.
Coreografia total sem visibilidade e SLA → dança descontrolada.
Ignorar deadline → reservas/colinas eternas.
18) Métricas de maturidade
90% dos processos críticos são cobertos por sagas/compensações e têm invariantes descritos.
O Outbox/inbox é integrado para todos os provedores/consórcios Tier-0/1.
SLO: pen95 end-to-end saga normal, sucess rate estável, orphaned <alvo.
Traçado transparente e dashboards a passos, burn-rate alert.
Game-day trimestral e verificação de compensações de runbook manual.
19) Conclusão
A saga é um contrato prático de coerência para sistemas distribuídos, como passos claros e retrocessos, disciplina de publicação (outbox/inbox), deadline e retais, observabilidade e processos de compensação. Selecione um modelo (orquestração/coreografia/TSS), fixe os invariantes e as chaves, torne os processadores idumpotentes - e seus processos de negócios multifacetados se tornarão previsíveis e sustentáveis sem um 2PC caro.