Message Broker: O guia definitivo
Profile picture

Junior Alves

Senior Developer

Foto: Unsplash

Atualizado: 23 de junho de 2025 às 08:16

Leitura: 5 minutos de leitura

Criado: 23 de junho de 2025

Message Broker: O guia definitivo

Uma introdução com exemplos práticos em Node.js

Introdução

Como você pode perceber, recentemente iniciei uma série de posts sobre Arquitetura de Software, System Design, Observabilidade e outros tópicos.Inclusive, vamos ter muuuito conteúdo sobre esses assuntos por aqui.
E se você ainda não viu os posts anteriores, confere lá, vão te ajudar a iniciar seus estudos nessa etapa na sua carreira.

O cenário

Vamos começar imaginar essa cena: um cliente clica em "Finalizar Compra" no seu e-commerce. Nos bastidores, uma sequência de tarefas é disparada: o serviço de Pagamentos é acionado, depois o de Estoque para dar baixa no produto, em seguida o de Notificações para enviar o e-mail de confirmação e por fim, o de Logística.
Tudo parece lógico e coeso. Mas e se o serviço de e-mails estiver fora do ar? O sistema inteiro trava? A compra do cliente é cancelada por causa de um simples e-mail de confirmação?
Se você disser que "sim", ou que você não sabe do que estou falando, esse artigo é para você.

O acoplamento

Esse efeito dominó acontece quando as partes de um sistema estão tão intimamente conectadas que a falha em uma derruba todas as outras.
Elas estão dependentes e frágeis.

Acoplamento é o nível interdependência entre módulos ou serviços. É basicamente op grau de 'intimidade' que existe entre dois ou mais serviços.

Uma solução simples, mas poderosa

E se, em vez de um serviço 'telefonar' diretamente para o outro, ele simplesmente deixasse uma mensagem em um "quadro de aviso" central e seguisse com sua vida?
Os outros serviços poderiam pegar essa mensagem quando estiverem prontos. É exatamente essa mágica que um Message Broker faz.

O Message Broker

Um Message Broker atua como um serviço do correios (mas que funciona hehe) para a aplicação. Um serviço (o Producer) não precisa saber onde o outro serviço (o Consumer) mora. Ele apenas escreve uma carta (a Message), e a entrega na agência de correios (o Broker). Mais tarde, o destinatário vai até a sua caixa postal (Queue) e retira a carta para ler quando puder.

Producer (Remetente): O serviço que origina a mensagem. (Ex: Serviço de Pedidos)
Consumer (Destinatário): O serviço que recebe e processa a mensagem. (Ex: Serviço de Notificações)
Message (A carta): O pacote de dados enviado. (Ex: { "orderId": 123, "client": "client@email.com", "status": "confirmed" }). Queue / Topic (A caixa postal ou quadro de aviso): O local dentro do Broker onde a mensagem fica armazenada temporariamente.

Filas VS Tópicos

Filas (Queues) — Comunicação Ponto-a-Ponto:

Analogia: Uma Fila (Queue) funciona como uma caixa de correio pessoal. Uma mensagem é entregue à fila e apenas um Consumer pode pegá-la. Depois que a mensagem é lida, ela desaparece. É o modelo perfeito para tarefas que devem ser executadas uma única vez, como 'enviar o e-mail de confirmação do pedido 456'. Imagem de uma representação simples de uma fila

Tópicos (Topics) — Padrão Publish/Subscribe:

Analogia: Um Tópico (Topic) é como um quadro de avisos público. O Producer 'prega' um aviso no quadro (Ex: 'O pedido 456 foi enviado!'). Vários Consumers interessados nesse tipo de aviso (Logística, Análise de Dados, Notificações) podem, cada um, ler uma cópia da mensagem e tomar suas próprias ações, sem que um interfira no outro. Imagem de uma representação simples de um tópico

Mão na massa

Para este exemplo, vamos usar Node.js e RabbitMQ.
A maneira mais fácil de rodar o RabbitMQ localmente é com Docker:
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management

producer.js

// Este script se conecta ao RabbitMQ, garante que uma fila chamada 'pedidos' exista, e envia uma mensagem para ela.
 
const amqp = require('amqplib');
 
async function sendOrder() {
  const connection = await amqp.connect('amqp://localhost');
  const channel = await connection.createChannel();
  const queue = 'pedidos';
  const msg = JSON.stringify({ pedidoId: 123, cliente: 'joao@email.com' });
 
  await channel.assertQueue(queue, { durable: true }); // Garante que a fila exista e sobreviva a reinicializações
  channel.sendToQueue(queue, Buffer.from(msg));
 
  console.log(" [x] Pedido enviado: '%s'", msg);
 
  setTimeout(() => {
    connection.close();
    process.exit(0);
  }, 500);
}
 
sendOrder();

consumer.js

// Este script se conecta ao RabbitMQ e fica 'escutando' a fila 'pedidos'.
// Quando uma mensagem chega, ele a processa.
 
const amqp = require('amqplib');
 
async function processOrder() {
  const connection = await amqp.connect('amqp://localhost');
  const channel = await connection.createChannel();
  const queue = 'pedidos';
 
  await channel.assertQueue(queue, { durable: true });
  console.log(" [*] Aguardando por pedidos na fila '%s'. Pressione CTRL+C para sair.", queue);
 
  channel.consume(queue, (msg) => {
    if (msg !== null) {
      console.log(" [✔] Pedido recebido:", msg.content.toString());
      // Aqui entraria a lógica de negócio (ex: enviar um e-mail, atualizar o estoque)
      channel.ack(msg); // Confirma que a mensagem foi processada com sucesso
    }
  });
}
 
processOrder();

Pratique para fixar 🎉

Qual é o principal problema que os Message Brokers buscam resolver em uma arquitetura de software?

1 / 5

Conclusão

Adotar Message Brokers não é apenas sobre usar uma nova tecnologia, não é sobre hype, é sobre evoluir como arquiteto de software. Suas aplicações se tornam:

  • Mais Resilientes: O sistema continua funcionando mesmo que um serviço falhe.
  • Mais Escaláveis: Se o processamento de e-mails está lento, basta adicionar mais Consumers de e-mail, sem tocar em mais nada.
  • Mais Flexíveis: A comunicação indireta permite que você troque, atualize ou adicione novos serviços sem quebrar o que já existe.

E você? Já usou um Message Broker em algum projeto? Qual foi sua maior dificuldade? Compartilhe sua experiência nos comentários!

Obrigado por ler até aqui, grande abraço e até o próximo post!

Curtiu? Compartilhe esse post:

Todos os direitos reseverdos © Junior Alves 2025