Pular para o conteúdo

apps/infrastructure/rabbitmq

176 · Infraestrutura em Docker · ≈ 7 min de estudo

RabbitMQ — liquidação de pagamentos com retry e DLQ

RabbitMQ é um broker AMQP: o publisher não conhece os consumidores, publica numa exchange com uma routing key e a topologia decide o destino. Aqui ele roda com a topologia completa de um worker de produção — topic exchange, publish confirmado com mandatory, prefetch, ack manual, retry atrasado por filas com TTL e dead letter queue. Use quando cada evento precisa ser processado uma vez com garantia, e falhas não podem sumir nem travar a fila.

passos
6
arquivos
8
testes
0
tecnologias
4
Infraestrutura realTypeScriptBunRabbitMQDocker
Baixar cartão

Cenário

O motor de pagamentos publica um evento por PIX, TED ou cartão decidido. A liquidação só processa aprovados; um recusado não tem fila, e com mandatory o broker o devolve ao publisher em vez de confirmar e descartar em silêncio. O banco recebedor de uma conta fica fora nas duas primeiras tentativas: o pagamento espera 1 s e 5 s em filas de retry e liquida na terceira. Um PIX de R$ 0 nunca vai liquidar e vai direto para a DLQ; outro, cujo banco nunca volta, chega lá quando os retries acabam.

Planta

Fluxo
11/11
Publisherconfirm channel + mandatorypayments.eventstopic, durablepayments.settlementDLX payments.dlxWorker de liquidaçãoLiquidadoretry.1000 / retry.5000TTL fixo por filapayments.dlxpayments.settlement.dlqdlqDrain lê x-deathpayment.pix.approvedpayment.pix.refusedsem binding:basic.returnpayment.*.approvedprefetch 5sucesso: ackfalha transitória:cópia confirmada + ackTTL expirapermanente, JSONinválido ou retriesesgotados: nack
11

11 passos — reproduza para seguir o fluxo

  1. 01

    paymentsTopologyAssert declara exchanges, filas, bindings, DLX e as filas de retry — idempotente, chamado por todo processo

  2. 02

    paymentPublish usa confirm channel com mandatory e persistent: resolve só quando o broker gravou e roteou; sem fila, rejeita com ErrorPaymentUnroutable

  3. 03

    O worker aplica prefetch (a concorrência dele) e dá ack só depois da liquidação

  4. 04

    Falha transitóriaPublica a cópia confirmada na fila de retry do degrau (x-attempt + 1) e só então dá ack na original; o TTL da fila devolve a mensagem à liquidação

  5. 05

    Falha permanente, JSON inválido ou degraus esgotados: nack sem requeue, e a DLX da fila leva à DLQ com o header x-death escrito pelo broker

  6. 06

    stop() cancela o consumer, espera o que está em processamento dar ack e fecha o canal; o demo conecta com recovery, que refaz canal, topologia e consumer a cada reconexão

Trade-offs

O que se ganha, o que se paga

Decisão Ganho Custo
Confirm channel + mandatory Publisher sabe que o evento foi gravado e tem destino Uma ida e volta a mais por publish
Ack manual depois do efeito Nenhum pagamento se perde numa queda Reentrega possível: o consumidor precisa ser idempotente
Retry por filas de TTL fixo Atraso real entre tentativas, sem loop quente Uma fila por degrau; mudar o TTL exige fila nova
DLQ em vez de requeue Mensagem envenenada não trava a fila Alguém precisa monitorar e reprocessar a DLQ

apps/infrastructure/rabbitmq

8 arquivos

src/

  • topology_payments.tsExchanges, filas, bindings, DLX e filas de retry com TTL
  • publisher_payments.tsPublish confirmado com mandatory e detecção de basic.return
  • worker_settlement.tsConsumer com prefetch, ack manual, retry por TTL, DLQ e parada limpa
  • settlement_bacen.tsLiquidação simulada: falha permanente e banco indisponível
  • dlq_inspect.tsDrena a DLQ lendo o x-death
  • config_rabbitmq.tsConfiguração validada do ambiente
  • demo.tsdemoPublica o lote, roda o worker com recovery e mostra a DLQ

./

  • docker.shinfraSobe o RabbitMQ com management e espera o listener AMQP

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

Management UI: http://localhost:15672 (guest / guest).

Requisitos
BunDocker
Sobe junto
RabbitMQ
Esc

↑ ↓ navegarEnter abrir191 resultados