Skip to main content

Fanout, Consumidores Offline e DLQ no RabbitMQ | RabbitMQ

  • Fanout, Consumidores Offline e DLQ no RabbitMQ | RabbitMQ

Conceitos fundamentais

O padrão fanout funciona como broadcast:

  • O producer publica em um exchange
  • O exchange replica a mensagem para todas as filas vinculadas
  • Cada fila possui seu próprio consumidor
  • Não existe dependência entre consumidores

Esse padrão segue o modelo de multiple-receiver (publish-subscribe)


Comportamento com consumidores offline

Cenário

  • 1 exchange fanout
  • 5 filas (1 por consumidor)
  • 1 consumidor offline

Resultado

  • A mensagem é entregue para todas as filas
  • O consumidor offline:
    • não processa
    • não confirma (ACK)
    • a mensagem permanece na fila

Observação importante

  • A mensagem não é perdida, desde que:
    • fila seja durável (durable = true)
    • mensagem seja persistente (delivery_mode = 2)

Confirmação de mensagem (ACK)

Existem dois níveis distintos:

Confirmação do producer (Publisher Confirm)

  • O broker confirma que recebeu a mensagem
  • Independe dos consumidores
  • Acontece normalmente mesmo com consumidores offline

Confirmação do consumidor (ACK)

  • Cada consumidor confirma individualmente
  • Se estiver offline:
    • não há ACK
    • mensagem fica pendente

Dead Letter Queue (DLQ)

A DLQ (Dead Letter Queue) é uma fila de fallback para mensagens que falharam.

Importante

  • DLQ não é usada para consumidores offline
  • DLQ é usada para falhas de processamento

Quando a DLQ é acionada

A mensagem vai para DLQ quando ocorre:

  • basic.nack com requeue = false
  • basic.reject com requeue = false
  • Expiração por TTL
  • Fila atinge limite (max-length)
  • Outras regras de dead-letter configuradas

Fluxo completo


Producer

Exchange (fanout)

Fila A → Consumer OK → ACK
Fila B → Consumer OFF → mensagem fica na fila
Fila C → Consumer ERRO → NACK (requeue=false) → DLQ


Exemplo em C# (NACK para DLQ)

var factory = new ConnectionFactory() { HostName = "localhost" };

using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

// rejeita mensagem e envia para DLQ
channel.BasicNack(deliveryTag: ea.DeliveryTag, multiple: false, requeue: false);

Configuração de DLQ

Criação da fila principal com DLQ

var args = new Dictionary<string, object>
{
{ "x-dead-letter-exchange", "dlx-exchange" }
};

channel.QueueDeclare(
queue: "fila-principal",
durable: true,
exclusive: false,
autoDelete: false,
arguments: args
);

Criação da DLQ

channel.ExchangeDeclare("dlx-exchange", ExchangeType.Direct);

channel.QueueDeclare(
queue: "fila-dlq",
durable: true,
exclusive: false,
autoDelete: false
);

channel.QueueBind(
queue: "fila-dlq",
exchange: "dlx-exchange",
routingKey: ""
);

Diferença conceitual

SituaçãoComportamento
Consumidor offlineMensagem fica na fila
Erro no processamentoPode ir para DLQ
TTL expiradoVai para DLQ
Fila cheiaVai para DLQ

Insight arquitetural

  • Fanout desacopla consumidores completamente
  • Cada fila representa um “destino independente”
  • DLQ trata mensagens problemáticas, não indisponibilidade

Esse modelo é típico de arquiteturas orientadas a eventos, onde componentes reagem de forma independente


Padrão recomendado em produção

  • Retry com requeue controlado
  • Retry com delay (ex: exchange de retry)
  • DLQ como fallback final
  • Monitoramento de filas (backlog)