← Microservices: desenhar fronteiras e operar sistemas distribuídos
08 / 12 · 60 MIN

Replay, sequências e reconciliação

Planeia recuperação de eventos sem esconder lacunas, duplicar efeitos ou ultrapassar capacidade.

1. Identidade não é ordem

Deduplicação responde se uma ocorrência já foi aplicada naquele âmbito. Sequência responde se as dependências necessárias estão satisfeitas. O fixture exige números consecutivos por agregado: se espera 1 e recebe 2, devolve sequence-gap e não grava conclusão. Depois de aplicar 1, pode recuperar 2. No ensaio, os valores 7 e 9 produzem total 16 e duas marcas. A regra é específica deste exercício; outros contratos podem aceitar eventos fora de ordem ou usar snapshots. Escolhe a política com base no significado dos dados, não apenas na ordem em que a rede entregou as mensagens.

2. Isolar uma mensagem não resolve a dependência

Uma quarentena ou DLQ retira trabalho que precisa de diagnóstico, mas o negócio pode continuar dependente desse trabalho. Se 19 depende de 18, repetir 19 não substitui o efeito em falta. Não avances um contador nem insiras uma marca de conclusão só para escoar a fila. Define como corrigir o evento, interpretar a versão ou executar recuperação autorizada, preservando a referência original. A documentação SQS alerta para consequências de DLQ quando a ordem importa; esse comportamento de fornecedor não deve ser generalizado para todos os brokers. O plano de recuperação tem de conhecer o produto realmente usado.

3. Reconstruir uma projeção é um efeito novo

Uma projeção v2 vazia não fica preenchida porque v1 já processou os eventos. O laboratório demonstra âmbitos de consumidor distintos: o mesmo evento é aplicado uma vez em cada projeção. Numa migração, cria um destino isolado, controla a interpretação dos schemas históricos e evita ativar efeitos externos durante a reconstrução. CloudEvents specversion identifica o formato do envelope; não é a versão do modelo de negócio. Usa o contrato de type e dataschema quando aplicável. Compara contagens e valores relevantes antes do corte, e mantém uma decisão explícita sobre o que fazer se o histórico estiver incompleto.

4. Medir idade e capacidade líquida

A query do ensaio filtra published=0 antes de calcular count e min(created). Com pendentes nos ticks 10 e 80 e agora=100, obtém dois pendentes e idade máxima de 90 ticks. Um evento já publicado no tick 1 fica fora da população. Profundidade pequena não significa impacto pequeno se o item antigo bloqueia um fecho. Para estimar escoamento, considera também chegadas: num modelo com backlog 100, entradas 20/s e processamento 25/s, a capacidade líquida é 5/s e a previsão é 20 segundos. Isto não é uma medição de desempenho nem uma garantia de SLA.

5. Preparar um replay controlado

Antes de reenviar, delimita eventos e consumidores, confirma a causa corrigida, a política de identidade e a capacidade disponível. Mantém pontos de paragem se aumentarem erros, idade ou saturação da dependência. Não alteres IDs históricos para contornar deduplicação sem compreender os efeitos. Para investigar payloads sensíveis, usa uma referência com acesso restrito e um exemplo mínimo redigido; evita replicar dados pessoais em canais amplos ou baggage. Uma equipa de suporte precisa de conseguir explicar quais operações foram recuperadas, quais continuam por decidir e quem autoriza novas tentativas. O número de mensagens enviadas não substitui essa reconciliação.

6. Demonstrar recuperação sem exagerar a evidência

Os dez grupos do laboratório verificam transações reais em SQLite, três saídas abruptas de processos e interrupções injetadas no relay e consumidor. A fila é local e não existe tráfego de rede. O ensaio não demonstra corte de energia, replicação, failover, autenticação, ordenação de um broker real ou efeitos externos. Para uma passagem a APS, complementa-o com ensaios representativos do sistema alvo, runbook de replay, permissões, responsáveis e reconciliação funcional. Regista estas limitações juntamente com resultados que passaram. Uma conclusão tecnicamente útil diz o que foi observado e quais fronteiras ainda precisam de prova.

SELECT count(*) AS pending, min(created) AS oldest_created
FROM outbox
WHERE published = 0;
-- Synthetic fixture: now=100, created=[10,80] -> pending=2, oldest_age=90.
NA PRÁTICA

sequence=2 chega primeiro e fica sem marca. Aplicam-se depois 1 e 2: duas marcas, sequência final 2, total 16.

Armadilhas comuns

Saltar lacunas; reutilizar inbox de outra projeção; confundir specversion com versão do payload; medir só profundidade; declarar SLA a partir de um modelo.

Tópicos relacionados: Transações e persistência · Eventos e identidade · Recuperação operacional

Leva esta ideia contigo

Uma recuperação termina com efeitos reconciliados e exceções assumidas, não apenas com menos mensagens pendentes.

Criar conta

Referência: Queue-based load leveling · Microservice architecture patterns and scoped platform examples; primary guidance consulted 2026-09-30