Idempotência e Deduplicação

Proteção completa nos consumers

Padronizando deduplicacao nos consumidores criticos com testes.

Avançado 40 min 35 pontos Leitura 0%

Nesta aula você vai

  • Aplicar idempotencia ponta a ponta nos consumidores criticos
  • Padronizar middleware reutilizavel de deduplicacao
  • Validar comportamento com testes de repeticao em lote

Proteção completa nos consumers

Objetivos

  • Aplicar idempotência ponta a ponta nos consumidores críticos
  • Padronizar middleware ou utilitário de deduplicação
  • Validar comportamento com testes de repetição em lote

Pré-requisitos

  • Aulas 1 e 2 de idempotencia-eventos concluidas.
  • Deduplicacao persistida ja funcionando no payment-service.
  • Ambiente com pelo menos 2 replicas de payment-service para teste real.

Conceito

Idempotencia parcial gera lacunas: um servico descarta duplicata, outro repete efeitos colaterais. O objetivo agora e padronizar o comportamento em todos os consumidores sensiveis.

O padrao recomendado combina middleware + store transacional + metrica de duplicata descartada.

Estrutura de arquivos

  • shared/idempotency/handler.ts
  • services/payment-service/internal/consumers/order_created_consumer.go
  • services/notification-service/app/consumers/payment_approved_consumer.rb
  • services/analytics-service/src/consumers/notificationSentConsumer.ts

Passo a passo com codigo

  1. Criar contrato comum de deduplicacao em shared:
export interface IdempotencyStore {
  tryReserve(eventId: string, consumer: string): Promise<boolean>;
}
  1. Aplicar no Payment Service antes do processamento:
if ok, _ := store.TryReserve(ctx, tx, event.EventID, "payment.order-created"); !ok {
  metrics.DuplicatesDiscarded.WithLabelValues("payment").Inc()
  return nil
}
  1. Aplicar no Notification Service com mesmo padrao:
reserved = idempotency_store.try_reserve(event["eventId"], "notification.payment-approved")
return if !reserved
send_email(event["data"])
  1. Criar teste de repeticao em lote:
for i in {1..50}; do
  kcat -b localhost:9092 -t payment.approved -P <<'EOF'
{"eventId":"evt-pay-77","eventType":"payment.approved","data":{"orderId":"ord-77"}}
EOF
done

Como testar

  1. Suba 2 replicas do Payment.
  2. Dispare eventos duplicados em lote (mesmo eventId).
  3. Verifique no banco que existe apenas um registro por evento.
  4. Consulte metricas duplicates_discarded_total.
  5. Confirme ausencia de efeitos duplicados (email e analytics).

Dicas

  • Centralize comportamento no shared/idempotency.
  • Exponha metrica de duplicata por servico e topico.
  • Mantenha logs com event_id e consumer_name.
  • Teste corrida com replicas simultaneas.

Erros comuns

  • Cobrir apenas payment-service.
  • Usar chaves diferentes para o mesmo consumidor logico.
  • Nao medir duplicatas descartadas.
  • Misturar deduplicacao com regra de envio de email.

Resumo

Com uma camada padronizada de idempotencia, os consumers do stack de 5 microsservicos passam a tratar redelivery de forma previsivel, auditavel e segura em escala.