Pular para o conteúdo

apps/messaging-streaming/dead-letter-queue

054 · Comunicação & Mensageria · ≈ 6 min de estudo

Dead-Letter Queue (DLQ)

Fila que recebe a mensagem que não pode ser processada — corrompida, recusada ou com as retentativas esgotadas — em vez de deixá-la em loop na fila principal ou descartá-la sem rastro. Lá ela é inspecionada, gera alerta e, corrigida a causa, é reprocessada.

passos
6
arquivos
9
teste
1
tecnologias
5
Infraestrutura realTypeScriptBunElysiaRabbitMQDocker
Baixar cartão

Cenário

Um banco digital liquida pagamentos PIX e TED num PSP. Mensagem corrompida, pagamento acima do limite do PSP e banco do pagador fora do ar não podem travar a fila nem sumir: cada um vai à DLQ com o motivo, a origem e o trace id, a equipe é alertada, e quando o banco volta os pagamentos estacionados são reenviados com o mesmo id.

Planta

Fluxo
12/12
Produtorpagamentospayment-settlefila principalWorker de liquidaçãoPSPHTTPpayment-settle-retry-500fila de atrasopayment-dlxpayment-settle-dlqInspetor da DLQpayment-settle-parkedReplayfalha transitória,abaixo do limiteTTL expirapoison, recusa 4xxou limite estourado:nack requeue=falseTTL da fila expiralog, alerta, ackapós a correção
12

12 passos — reproduza para seguir o fluxo

  1. 01

    payment-settle é declarada com x-dead-letter-exchange e TTL; a DLQ é ligada na DLX antes de qualquer rejeição

  2. 02

    Poison pill (JSON inválido ou fora do schema) e recusa 4xx do PSP → nack com requeue=false na hora, sem retry

  3. 03

    Falha transitória (5xx, timeout, conexão recusada) → cópia confirmada na fila de atraso, que devolve à principal ao expirar; x-death[].count conta as tentativas

  4. 04

    Estourado o limite (PAYMENT_RETRY_MAX) → nack sem requeue → DLX → DLQ

  5. 05

    O inspetor lê x-death, x-origin-service e x-trace-id, registra o log de erro, incrementa o alerta, estaciona a mensagem e faz ack; /metrics expõe o total e a profundidade

  6. 06

    Corrigida a causa, replay_dlq.ts republica os estacionados na fila principal sem x-death, com o mesmo messageId, e remove cada um só depois do confirm

apps/messaging-streaming/dead-letter-queue

9 arquivos

src/

  • topology_payment.tsExchange, fila principal com DLX e TTL, fila de atraso, DLQ, estacionamento, contagem por x-death e publicação confirmada
  • config_payment.tsVariáveis de ambiente validadas no boot
  • api_psp.tsPSP em Elysia: liquida, recusa acima do limite (422) ou responde 503 para banco fora do ar
  • worker_payment.tsClassifica a falha: poison e 4xx para a DLQ, transitória para a fila de atraso até o limite
  • worker_dlq.tsInspetor da DLQ: diagnóstico, alerta, estacionamento, ack e métricas
  • replay_dlq.tsReprocessamento controlado, com --dry-run
  • worker_payment.test.tstesteIntegração com RabbitMQ real: poison sem retry, limite exato, recuperação na última tentativa, TTL, estacionamento e replay
  • demo.tsdemoSobe PSP, worker e inspetor e percorre os quatro destinos de um pagamento

./

  • docker.shinfraSobe o RabbitMQ 3 na porta 5672

Executar · com Docker

  1. ./docker.sh up# sobe RabbitMQ
  2. cp .env.example .env# variáveis de ambiente
  3. bun install# dependências
  4. bun run demo# roda o cenário
  5. bun run test# integração contra o serviço real
  6. bun run replay -- --dry-run
  7. bun run replay -- 100

Replay manual, depois de corrigir a causa:

Requisitos
BunDocker
Sobe junto
RabbitMQ

Por que se relacionam

Teste rápido

Qual padrão vem antes de Dead Letter Queue?

Próximo projeto · Comunicação & MensageriaMessage Routing
Esc

↑ ↓ navegarEnter abrir191 resultados