Configurando Filas e Trocas Duráveis para Mensagens Confiáveis
Configure filas, trocas, vínculos e mensagens persistentes do RabbitMQ para que trabalhos críticos sobrevivam a reinicializações do broker.
Configurando Filas e Trocas Duráveis para Mensagens Confiáveis
Quando suas aplicações usam RabbitMQ para tarefas, pedidos ou notificações, uma reinicialização do broker não deve apagar o trabalho ainda aguardando em uma fila. Filas duráveis, trocas duráveis, vínculos duráveis e mensagens persistentes são as peças que tornam o RabbitMQ confiável em reinicializações.
Este guia mostra as configurações necessárias, onde as pessoas geralmente erram e como verificar o comportamento antes de confiar nele em produção.
Entendendo Durabilidade vs. Persistência
Antes de configurar, é crucial distinguir entre os dois conceitos principais relacionados à sobrevivência de mensagens:
- Durabilidade da Fila: Refere-se à definição da fila em si. Uma definição de fila durável sobrevive a uma reinicialização do broker. Se a fila for declarada como não durável, ela é excluída quando o broker para.
- Durabilidade da Troca: Refere-se à definição da troca. Trocas duráveis sobrevivem a reinicializações; trocas não duráveis são removidas quando o broker para.
- Durabilidade do Vínculo: Vínculos entre trocas duráveis e filas duráveis são recuperados com a topologia durável. Vínculos que envolvem entidades transitórias desaparecem com essas entidades.
- Persistência da Mensagem: Refere-se a como mensagens individuais são tratadas. Uma mensagem persistente é gravada em disco pelo broker, garantindo que sobreviva a uma reinicialização do broker, mesmo que a fila em si seja durável. Mensagens marcadas como transitórias (não persistentes) são mantidas apenas em memória e podem ser perdidas durante uma reinicialização.
Para que uma mensagem sobreviva a uma reinicialização do broker, a fila deve ser durável e a mensagem deve ser publicada como persistente. Na publicação roteada normal, a troca e o vínculo também precisam retornar para que produtores e consumidores possam continuar usando a mesma topologia.
Passo 1: Declarando uma Fila Durável
As filas devem ser explicitamente declaradas como duráveis quando criadas. Isso informa ao RabbitMQ para salvar os metadados da fila em disco para que ela possa ser recriada automaticamente quando o broker voltar ao ar.
Esta configuração é tipicamente feita através da biblioteca cliente (cliente AMQP) conectando-se ao broker. Abaixo estão exemplos ilustrando a declaração em ferramentas comuns.
Exemplo usando a CLI rabbitmqadmin (ou ferramenta similar)
Ao declarar uma fila usando ferramentas de linha de comando, você especifica o argumento durable como true.
# Comando para declarar uma fila chamada 'high_priority_tasks' como durável
rabbitmqadmin declare queue name=high_priority_tasks durable=true
Exemplo usando Python (biblioteca pika)
Em um contexto programático, o parâmetro durable no método channel.queue_declare() deve ser definido como True.
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
queue_name = 'order_processing_queue'
channel.queue_declare(
queue=queue_name,
durable=True # <-- Definindo durabilidade aqui
)
print(f"Fila '{queue_name}' declarada como durável.")
# connection.close() # (Feche a conexão após outras operações)
Aviso sobre Declaração de Fila: Se uma fila já existir e você tentar redeclarar com atributos diferentes (por exemplo, mudando de não durável para durável), o RabbitMQ levantará um erro (
Precondition Failedou similar) porque filas existentes não podem mudar seu status de durabilidade.
Passo 2: Declarando uma Troca Durável
Trocas, que roteiam mensagens para filas, também devem ser declaradas como duráveis se você depender delas para sobreviver a uma reinicialização do broker. Se uma troca for não durável, ela será excluída na reinicialização, e quaisquer vínculos associados a ela também serão perdidos.
Exemplo usando Python (biblioteca pika para Declaração de Troca)
Similar às filas, as trocas exigem que o argumento durable seja definido como True durante a declaração.
import pika
# Suponha que a conexão e o canal já estejam estabelecidos
exchange_name = 'critical_events_exchange'
channel.exchange_declare(
exchange=exchange_name,
exchange_type='direct',
durable=True
)
print(f"Troca '{exchange_name}' declarada como durável.")
Passo 3: Publicando Mensagens Persistentes
Declarar filas e trocas duráveis apenas garante que a topologia sobreviva. Para garantir que as mensagens em si sobrevivam, o publicador deve marcar as propriedades da mensagem como persistentes.
Ao publicar, você define a propriedade delivery_mode como 2 (que significa persistente).
Exemplo: Publicando Mensagens Persistentes (Pika)
Na chamada channel.basic_publish, o argumento properties é usado para definir a persistência da mensagem.
import pika
from pika import BasicProperties
# ... configuração do canal ...
message_body = "Este pedido não deve ser perdido!"
exchange = 'critical_events_exchange'
routing_key = 'urgent'
channel.basic_publish(
exchange=exchange,
routing_key=routing_key,
body=message_body,
properties=BasicProperties(
delivery_mode=2 # <-- Modo de Entrega 2 = Persistente
)
)
print("Mensagem publicada persistentemente.")
Melhor Prática: Confirmações do Publicador: Embora a persistência salve dados durante uma reinicialização do broker, ela não garante que o broker recebeu a mensagem antes que a aplicação publicadora falhe. Para máxima confiabilidade, sempre emparelhe configurações duráveis/persistentes com Confirmações do Publicador para receber confirmação do broker de que a mensagem foi gravada com segurança em disco.
Passo 4: Vinculando Componentes Duráveis
Uma vez que a fila durável e a troca persistente são criadas, você deve vinculá-las. Vínculos definem a lógica de roteamento. Se a troca for durável, os vínculos associados a ela geralmente também devem ser duráveis para garantir que a estrutura de roteamento esteja imediatamente funcional após a reinicialização do broker.
# ... configuração do canal ...
exchange_name = 'critical_events_exchange'
queue_name = 'order_processing_queue'
routing_key = 'urgent'
channel.queue_bind(
exchange=exchange_name,
queue=queue_name,
routing_key=routing_key
)
print(f"Vínculo estabelecido entre {exchange_name} e {queue_name}.")
No RabbitMQ, vínculos entre filas duráveis e trocas duráveis são duráveis. Se qualquer lado for transitório, o vínculo não pode sobreviver àquela entidade.
Resumo da Lista de Verificação de Confiabilidade
Para alcançar confiabilidade de mensagem de ponta a ponta contra falha do broker, certifique-se de que todos os três componentes estão configurados corretamente:
| Componente | Configuração Necessária | Propósito |
|---|---|---|
| Fila | durable=True |
Sobrevive à reinicialização do broker (metadados salvos). |
| Troca | durable=True |
Sobrevive à reinicialização do broker (topologia salva). |
| Vínculo | Fila durável vinculada a troca durável | Relacionamento de roteamento é recuperado após reinicialização. |
| Mensagem | delivery_mode=2 (Persistente) |
Sobrevive à reinicialização do broker (dados gravados em disco). |
Conclusão
Durabilidade no RabbitMQ não é uma única chave. Declare filas e trocas duráveis, vincule entidades duráveis, publique mensagens com delivery_mode=2 e ative confirmações do publicador para que seu publicador saiba que o RabbitMQ aceitou a mensagem. Em seguida, reinicie um broker não produtivo e verifique se a fila, o vínculo e a mensagem persistente não consumida ainda estão lá.