Os message brokers são aplicações intermediárias utilizadas em várias arquiteturas de software, como microservices. Eles transferem informações em forma de mensagens de um serviço para outro.
Um conceito comum associado aos message brokers é o padrão publicador-assinante (publisher-subscriber), no qual os eventos são enviados pelos publicadores (Produtores) para os assinantes (Consumidores).

Geralmente, um componente intermediário — um message broker — participa da implementação desse padrão.

Para simplificar, vejamos uma analogia. Pense no YouTube: há canais aos quais você pode se inscrever para receber notificações. Quando um novo vídeo é publicado (um evento), você é notificado porque está inscrito.

Três termos principais são importantes aqui: Exchange, Queue e Binding.

Outros termos importantes:
Aqui está uma explicação passo a passo de como o processo funciona:





RabbitMQ é um popular message broker de código aberto baseado no AMQP (Advanced Message Queuing Protocol), um protocolo aberto para a transmissão de mensagens de eventos por meio de um broker dedicado. O AMQP oferece uma ampla gama de recursos e, além do RabbitMQ, é implementado por outros sistemas, como o Apache Qpid.
RabbitMQ é escrito na linguagem de programação Erlang, e suas principais vantagens são o alto desempenho e a máxima flexibilidade de roteamento. RabbitMQ oferece diversas opções de configuração para definir regras sobre quais mensagens são enviadas e para onde devem ser processadas.
As conexões com o RabbitMQ são feitas por meio do protocolo TCP: o cliente inicia uma conexão com o endereço do host e a mantém aberta enquanto a interação for necessária. O RabbitMQ também oferece suporte à autenticação (usuário e senha) para garantir o acesso seguro.
O RabbitMQ é composto pelo servidor e pela interface web (WebUI). A WebUI permite monitorar o que está acontecendo dentro do broker, como verificar se os nós do cluster estão ativos, quantas mensagens estão sendo processadas e muito mais. Vamos ver como instalar o RabbitMQ em diferentes sistemas operacionais.
Antes de começar, precisamos atualizar o nome do host do servidor. Execute o seguinte comando:
sudo hostnamectl set-hostname <novo-hostname>
Por exemplo, usaremos rabbitmq como nome do host neste servidor:
sudo hostnamectl set-hostname rabbitmq
Instale o nano:
sudo apt install nano
E adicione o novo nome de host no arquivo /etc/hosts:
sudo nano /etc/hosts
Ele deve ficar assim:
127.0.0.1 <novo-hostname>
No nosso exemplo:
127.0.0.1 rabbitmq
Instalaremos o RabbitMQ no Ubuntu 22.04. Para outras distribuições Ubuntu/Debian, consulte o guia no site oficial.
Atualize a lista de pacotes e instale as dependências:
sudo apt-get update -y
sudo apt-get install curl gnupg -y
sudo apt-get install apt-transport-https
Adicione as chaves de assinatura do repositório:
curl -1sLf "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" | sudo gpg --dearmor | sudo tee /usr/share/keyrings/com.rabbitmq.team.gpg > /dev/null
curl -1sLf https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-erlang.E495BB49CC4BBE5B.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg > /dev/null
curl -1sLf https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-server.9F4587F226208342.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/rabbitmq.9F4587F226208342.gpg > /dev/null
Crie o arquivo de repositório (Apt Source List):
sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu jammy main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu jammy main
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu jammy main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu jammy main
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu jammy main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu jammy main
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu jammy main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu jammy main
EOF
Atualize novamente a lista de pacotes:
sudo apt-get update -y
Instale o Erlang:
sudo apt-get install -y erlang-base \
erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
erlang-runtime-tools erlang-snmp erlang-ssl \
erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
Por fim, instale o RabbitMQ:
sudo apt-get install rabbitmq-server -y --fix-missing
Após a instalação, verifique se o servidor RabbitMQ está em execução:
systemctl status rabbitmq-server
Crie um usuário personalizado:
sudo rabbitmqctl add_user <seu-usuario> <sua-senha>
Conceda as permissões necessárias:
sudo rabbitmqctl set_user_tags <seu-usuario> administrator
sudo rabbitmqctl set_permissions -p / <seu-usuario> ".*" ".*" ".*"
Agora ative o console de gerenciamento do RabbitMQ:
sudo rabbitmq-plugins enable rabbitmq_management
Acesse [seu IP do servidor]:15672. Insira seu nome de usuário e senha para acessar a interface web do RabbitMQ.

O guia de instalação está disponível no site do RabbitMQ. Você pode usar o Chocolatey ou o instalador clássico.
Antes de instalar o RabbitMQ, é necessário instalar o Erlang/OTP no site oficial do Erlang.

Execute o arquivo baixado e siga o processo de instalação.
Depois de instalar o Erlang, você pode instalar o RabbitMQ usando o instalador oficial.
Ative a interface web:
cd 'C:\Program Files\RabbitMQ Server\rabbitmq_server-3.13.0\sbin'
./rabbitmq-plugins.bat enable rabbitmq_management
Agora você pode acessar localhost:15672 usando o nome de usuário e senha padrão guest:guest.
Instalar usando o Docker é provavelmente a forma mais simples e conveniente de configurar o RabbitMQ.
Você pode instalar o RabbitMQ com o comando:
docker run --rm -p 15672:15672 rabbitmq:3.13.7-management
A interface de administração estará disponível na porta 15672, onde você pode fazer login com as credenciais padrão guest:guest.
No entanto, esse método não é adequado para ambientes de produção. O Docker atribui um nome de servidor ao contêiner, e o broker armazena seu estado em uma pasta com esse nome. A cada nova compilação do contêiner, o RabbitMQ perderá as informações de estado.
Podemos definir facilmente todos os parâmetros de serviço necessários com o docker-compose, como alterar o login e senha padrão ou montar uma pasta para persistência de estado. Veja um exemplo de arquivo docker-compose.yml:
version: "3.3"
services:
rabbit:
image: rabbitmq:3.13.7-management
environment:
- RABBITMQ_DEFAULT_USER=admin #enter your username
- RABBITMQ_DEFAULT_PASS=password #enter your password
volumes:
- ./rabbit:/var/lib/rabbitmq # mounting folder for state persistence
ports:
- 15672:15672 # expose port for the admin interface
Execute:
docker compose up -d
A interface web do RabbitMQ agora estará disponível.
Na página principal da interface de gerenciamento do RabbitMQ, você pode ver informações gerais, como nós, status, número total de mensagens e muito mais.



Vamos analisar mais de perto os Exchanges.

Existem vários tipos de Exchanges, cada um com seu próprio mecanismo de filtragem de mensagens. Com base nessas regras, os eventos são roteados para filas específicas.
Direct Exchange
Cada mensagem tem uma chave chamada Routing Key. Essas mensagens serão roteadas para as filas cujo binding especifica a mesma chave.

Topic Exchange
O roteamento é feito com base em um padrão de chave. Ao criar o padrão, podem ser usadas zero ou mais palavras (letras e números) separadas por pontos, por exemplo key.event, e os símbolos # e *.

Fanout Exchange
Nenhuma regra de filtragem é aplicada. Cada mensagem enviada a um Fanout Exchange é roteada para todas as filas.

Headers Exchange
Usa os cabeçalhos das mensagens, comparando pares chave-valor com os cabeçalhos de binding.

Ao visualizar uma fila específica, você pode ver um gráfico mostrando quantas mensagens há na fila, além de estatísticas sobre os tempos de entrega e recebimento.

As mensagens podem ter dois estados:
Vamos ver como usar o RabbitMQ para implementar o padrão Pub-Sub em Python. Você deve ter o Python instalado (neste exemplo, versão 3.11.5) e a biblioteca Pika.
Crie ou selecione uma pasta onde ficará o código da aplicação:
mkdir rabbitmq-article
Abra essa pasta no seu IDE (por exemplo, Visual Studio Code ou PyCharm).
Instale a biblioteca Pika:
pip install pika
Crie dois arquivos: sender.py e receiver.py.
from pika import BlockingConnection, ConnectionParameters
from pika.exchange_type import ExchangeType
# Create connection, specifying parameters in the ConnectionParameters object
connection = BlockingConnection(ConnectionParameters(host='localhost'))
# Create a channel
channel = connection.channel()
# Declare an exchange
channel.exchange_declare('new_exchange', ExchangeType.direct)
# Declare a queue
queue = channel.queue_declare(queue='new_queue')
# Bind the queue to the exchange
channel.queue_bind(exchange='new_exchange', queue='new_queue', routing_key='key')
# Publish a message
channel.basic_publish(exchange='new_exchange', routing_key='key', body='Hello World!')
print("Message 'Hello World!' sent")
connection.close()
No código acima de sender.py:
Estabelecemos uma conexão com o RabbitMQ em localhost.
Declaramos um exchange direto chamado new_exchange.
Declaramos uma fila chamada new_queue.
Vinculamos a fila ao exchange usando a chave de roteamento key.
Por fim, publicamos a mensagem 'Hello World!' no exchange com a chave de roteamento especificada.
from pika import BlockingConnection, ConnectionParameters
from pika.exchange_type import ExchangeType
import sys, os
def main():
# Create connection
connection = BlockingConnection(ConnectionParameters(host='localhost'))
# Create channel
channel = connection.channel()
# Declare an exchange
channel.exchange_declare('new_exchange', ExchangeType.direct)
# Declare a queue
queue = channel.queue_declare(queue='new_queue')
# Bind the queue to the exchange
channel.queue_bind(exchange='new_exchange', queue='new_queue', routing_key='key')
# Function to handle incoming messages
def handle(ch, method, properties, body):
print(f"Received message: {body.decode()}")
# Bind the callback function and queue
channel.basic_consume(queue='new_queue', on_message_callback=handle, auto_ack=True)
print('Waiting for messages. Press Ctrl+C to exit.')
channel.start_consuming()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
try:
sys.exit(0)
except SystemExit:
os._exit(0)
No código acima de receiver.py:
Estabelecemos uma conexão e um canal com o RabbitMQ, assim como no sender.
Declaramos o exchange direto (new_exchange) e a fila (new_queue).
A fila é vinculada ao exchange usando a chave de roteamento key.
A função handle() processa as mensagens imprimindo-as quando recebidas.
O método basic_consume() associa a função de callback à fila.
Usamos start_consuming() para manter o processo aguardando mensagens indefinidamente.
Primeiro, inicie o receiver:
python receiver.py
Você verá:
Waiting for messages. Press Ctrl+C to exit.
Em seguida, execute o sender:
python sender.py
Saída:
Message 'Hello World!' sent
No terminal onde o receiver está em execução, você verá:
Received message: Hello World!
No console de gerenciamento do RabbitMQ, você pode ver que o exchange new_exchange está vinculado à fila new_queue usando a chave de roteamento key.
Neste artigo, exploramos o que são os message brokers, como as aplicações interagem com eles e como instalar e usar o RabbitMQ como broker de mensagens. Implementamos com sucesso um padrão publicador-assinante usando Python, RabbitMQ e a biblioteca Pika, onde o remetente publica mensagens em um exchange e o receptor as consome.