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.
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
- RabbitMQ Documentation
https://www.rabbitmq.com/docs - RabbitMQ Tutorials
https://www.rabbitmq.com/tutorials - RabbitMQ .NET Client
https://github.com/rabbitmq/rabbitmq-dotnet-client - Exchanges Explained
https://www.rabbitmq.com/tutorials/amqp-concepts - Dead Letter Exchanges
https://www.rabbitmq.com/dlx.html