Pular para o conteúdo
Diogo FC

Fase04/ 27

Usando RabbitMQ para comunicação assíncrona

RabbitMQ é um dos brokers de mensagens mais populares para comunicação assíncrona entre aplicações. Neste artigo veremos seus principais conceitos, quando utilizá-lo e como ele pode ajudar a criar sistemas mais desacoplados e resilientes.

4 min de leitura

O que é RabbitMQ?

RabbitMQ é um Message Broker responsável por receber, armazenar e distribuir mensagens entre aplicações.

Em vez de um serviço chamar outro diretamente, ele pode enviar uma mensagem para uma fila. Os consumidores processam essas mensagens posteriormente, reduzindo o acoplamento entre os sistemas.

Essa abordagem é muito utilizada em:

  • Processamento de pedidos;
  • Envio de e-mails;
  • Geração de relatórios;
  • Integrações entre sistemas;
  • Processos em background.

Conceitos principais

Producer

É a aplicação responsável por enviar mensagens para o RabbitMQ.

Exemplo:

  • API de pedidos enviando um evento de pedido criado.

Queue

As filas armazenam as mensagens até que algum consumidor as processe.

Exemplos:

  • email-queue
  • payment-queue
  • notification-queue

Consumer

É a aplicação que recebe e processa as mensagens.

Por exemplo:

  • Um serviço responsável por enviar e-mails.

Exchange

As exchanges recebem as mensagens dos producers e decidem para quais filas elas serão encaminhadas.

Existem quatro tipos principais:

  • Direct
  • Topic
  • Fanout
  • Headers

Fluxo básico

Producer
↓
Exchange
↓
Queue
↓
Consumer

Essa arquitetura permite desacoplar produtores e consumidores, facilitando manutenção e escalabilidade.

Exemplo prático

Imagine um e-commerce.

Quando um pedido é criado, várias ações precisam acontecer:

  • Processar pagamento;
  • Atualizar estoque;
  • Enviar e-mail;
  • Gerar nota fiscal.

Ao invés de a API fazer tudo isso diretamente, ela apenas envia uma mensagem.

Cliente
↓
API Pedidos
↓
RabbitMQ
↓
┌─────────────┬────────────┬─────────────┐
│ Pagamento │ Estoque │ E-mail │
└─────────────┴────────────┴─────────────┘

Assim, caso algum serviço esteja indisponível, as mensagens permanecem na fila aguardando processamento.

Enviando mensagens em .NET

Usando RabbitMQ.Client:

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

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

channel.QueueDeclare(
queue: "orders",
durable: true,
exclusive: false,
autoDelete: false);

var body = Encoding.UTF8.GetBytes("Pedido criado");

channel.BasicPublish(
exchange: "",
routingKey: "orders",
body: body);

A mensagem será enviada para a fila orders.

Consumindo mensagens

var consumer = new EventingBasicConsumer(channel);

consumer.Received += (model, ea) =>
{
var message = Encoding.UTF8.GetString(ea.Body.ToArray());

Console.WriteLine($"Mensagem recebida: {message}");
};

channel.BasicConsume(
queue: "orders",
autoAck: true,
consumer: consumer);

O consumidor ficará escutando a fila continuamente.

Tipos de Exchange

Direct Exchange

Envia mensagens para filas específicas através de uma routing key.

Ideal para:

  • Processamento de pedidos;
  • Filas simples.

Fanout Exchange

Distribui a mesma mensagem para várias filas.

Ideal para:

  • Notificações;
  • Logs;
  • Broadcast de eventos.

Topic Exchange

Permite utilizar padrões nas routing keys.

Exemplo:

order.created
payment.approved
user.registered

Muito útil em sistemas maiores.

Retry e Dead Letter Queue

Nem toda mensagem será processada com sucesso.

Por isso, é comum implementar:

Retry

Tenta processar novamente a mensagem após uma falha.

Dead Letter Queue (DLQ)

Mensagens que falharam várias vezes são enviadas para uma fila separada.

Queue Principal
↓
Erro
↓
Retry
↓
Falhou novamente
↓
Dead Letter Queue

Isso evita perda de mensagens e facilita investigação de problemas.

Quando utilizar RabbitMQ?

RabbitMQ é uma excelente escolha para:

  • Processamento em background;
  • Envio de e-mails;
  • Integrações entre microsserviços;
  • Filas de tarefas;
  • Processos assíncronos;
  • Sistemas com baixo ou médio volume de mensagens.

RabbitMQ x Kafka

RabbitMQKafkaBroker tradicionalPlataforma de streamingMenor complexidadeAlta escalabilidadeFácil configuraçãoMais complexoExcelente para filasExcelente para eventosMenor throughputAltíssimo throughput

Em muitos casos, RabbitMQ é mais simples e suficiente para atender às necessidades da aplicação.

Boas práticas

Utilize mensagens pequenas

Prefira enviar apenas os dados necessários.

Exemplo:

{
"orderId": 123
}

Em vez de enviar toda a estrutura do pedido.

Crie filas específicas

Evite utilizar uma única fila para tudo.

Por exemplo:

  • email-queue
  • payment-queue
  • invoice-queue

Implemente retries

Falhas acontecem. Sempre considere mecanismos de reprocessamento.

Torne consumidores idempotentes

Uma mesma mensagem pode ser processada mais de uma vez.

O sistema deve ser capaz de lidar com isso sem gerar inconsistências.

Monitore as filas

Acompanhe:

  • Quantidade de mensagens;
  • Tempo de processamento;
  • Taxa de erros;
  • Filas congestionadas.

Vantagens

  • Fácil configuração;
  • Grande comunidade;
  • Excelente para processamento assíncrono;
  • Alta confiabilidade;
  • Suporte a retries e DLQ;
  • Diversos padrões de roteamento.

Desvantagens

  • Não possui o mesmo throughput do Kafka;
  • Pode exigir planejamento em aplicações muito grandes;
  • Crescimento excessivo das filas pode gerar gargalos.

Conclusão

RabbitMQ é uma excelente solução para desacoplar aplicações e executar tarefas em segundo plano. Sua simplicidade e flexibilidade fazem dele uma escolha bastante comum em sistemas modernos.

Para a maioria das aplicações corporativas, RabbitMQ é mais do que suficiente para lidar com processamento assíncrono, oferecendo confiabilidade e facilidade de manutenção.

Saiba mais