RabbitMQ Clustering: Configuração, Configuração e Melhores Práticas

Desbloqueie o poder de mensagens escaláveis e resilientes com clustering RabbitMQ. Este guia cobre conceitos essenciais como tipos de nós, partições de rede e sincronização de dados. Aprenda passo a passo como configurar um cluster RabbitMQ, configurar filas de Alta Disponibilidade (HA) usando políticas e implementar melhores práticas para implantação e gerenciamento robustos. Perfeito para desenvolvedores e operadores que buscam construir aplicações orientadas a mensagens tolerantes a falhas.

RabbitMQ Clustering: Configuração, Configuração e Melhores Práticas

O clustering RabbitMQ é frequentemente mal compreendido. Um cluster oferece um broker lógico composto por múltiplos nós Erlang. Ele compartilha usuários, vhosts, exchanges, bindings, políticas e outros metadados entre esses nós. Ele não torna automaticamente as mensagens de cada fila disponíveis em todos os lugares. A disponibilidade da fila depende do tipo de fila e de suas configurações de replicação.

Essa diferença importa em produção. Um cluster pode facilitar o gerenciamento e o roteamento, e pode suportar filas altamente disponíveis, mas não é um interruptor mágico de desempenho. Se você colocar todas as filas quentes em um nó, esse nó ainda faz o trabalho. Se você usar filas clássicas sem replicação e o nó líder da fila desaparecer, essa fila fica indisponível até que o nó retorne. Projete o cluster em torno das filas que você realmente executa.

O que um cluster compartilha, e o que não compartilha

Os metadados do cluster RabbitMQ são replicados. Se você declarar uma exchange em um nó, os outros nós sabem disso. Se você adicionar um usuário ou política, o cluster armazena essa definição. Aplicações cliente podem se conectar a qualquer nó e usar a mesma topologia.

As mensagens são diferentes. Uma fila tem um líder. Para filas clássicas, as mensagens vivem no nó que hospeda essa fila, a menos que você use filas espelhadas mais antigas. Para filas de quorum, o RabbitMQ replica os dados da fila em um grupo de nós usando um protocolo de consenso. Para streams, os dados são replicados de acordo com a configuração do stream. Em implantações modernas do RabbitMQ, filas de quorum são geralmente a escolha mais segura para filas de trabalho duráveis e replicadas.

Artigos mais antigos frequentemente falam sobre "filas HA" como se fosse o padrão moderno. Na terminologia RabbitMQ, isso geralmente significa filas clássicas espelhadas configuradas por política. Elas ainda existem em algumas instalações, mas filas de quorum são a direção que a maioria dos novos designs de filas duráveis replicadas deve considerar. Sempre verifique a versão do RabbitMQ e as restrições operacionais do seu ambiente antes de migrar uma carga de trabalho existente.

Antes de juntar nós

Faça as verificações chatas primeiro:

  • Os nós devem resolver os hostnames uns dos outros de forma consistente.
  • A porta de distribuição Erlang e as portas RabbitMQ devem ser acessíveis entre os nós.
  • As versões do RabbitMQ e Erlang devem ser compatíveis em todo o cluster.
  • Todos os nós devem compartilhar o mesmo cookie Erlang.
  • A sincronização de tempo deve ser sã, especialmente se seu monitoramento e TLS dependerem disso.

O cookie Erlang é um segredo compartilhado usado pelos nós Erlang. Em muitos pacotes Linux, ele fica em /var/lib/rabbitmq/.erlang.cookie, de propriedade do usuário rabbitmq e modo 600.

sudo systemctl stop rabbitmq-server
sudo install -o rabbitmq -g rabbitmq -m 600 .erlang.cookie /var/lib/rabbitmq/.erlang.cookie
sudo systemctl start rabbitmq-server

Não regenere o cookie casualmente em um cluster em execução. Se um nó tiver um cookie diferente, ele falhará ao se comunicar com os outros, e a mensagem de erro nem sempre é amigável.

Juntando um nó

Suponha que rabbit@rmq-a já está em execução e rabbit@rmq-b deve juntar-se a ele. Em rmq-b:

sudo rabbitmqctl stop_app
sudo rabbitmqctl reset
sudo rabbitmqctl join_cluster rabbit@rmq-a
sudo rabbitmqctl start_app

Em seguida, verifique a partir de qualquer nó:

rabbitmqctl cluster_status
rabbitmq-diagnostics cluster_status

reset remove o banco de dados RabbitMQ do nó local antes de juntar. Isso é geralmente o que você quer para um novo nó vazio. Não é algo para executar casualmente em um nó que possui filas que você se importa.

Para três nós, repita o mesmo processo a partir de rmq-c. Você pode juntar tanto rmq-b quanto rmq-c a rmq-a; uma vez juntos, não há um nó "mestre" permanente para metadados da maneira que as pessoas às vezes imaginam.

Coloque clientes atrás de um endpoint estável

As aplicações não devem ter um host de broker codificado se você espera manutenção de nós. Use um balanceador de carga, estratégia de DNS ou uma lista de conexão da biblioteca cliente. O balanceador de carga deve verificar se a aplicação RabbitMQ está em execução, não apenas se a porta 5672 está aberta.

Uma verificação TCP simples pode enviar clientes para um nó que está vivo, mas bloqueado por alarmes ou não totalmente juntado. Em ambientes mais rigorosos, use verificações de saúde expostas através do plugin de gerenciamento ou uma pequena verificação local que executa rabbitmq-diagnostics -q ping.

Escolha tipos de fila deliberadamente

Para cargas de trabalho duráveis replicadas, uma fila de quorum é frequentemente um bom padrão:

rabbitmqadmin declare queue name=orders.pending durable=true arguments='{"x-queue-type":"quorum"}'

Ou através da declaração da aplicação:

channel.queue_declare(
    queue='orders.pending',
    durable=True,
    arguments={'x-queue-type': 'quorum'}
)

Filas de quorum trocam alguma taxa de transferência e latência por um comportamento de replicação mais forte. Elas não são uma atualização gratuita para toda fila. Para filas de resposta temporárias, assinantes fanout de curta duração ou trabalho transitório de baixo valor, filas clássicas podem ser suficientes. Para eventos de negócios que devem sobreviver à perda de nó, use um tipo de fila replicada e teste o failover.

Partições de rede são um evento operacional, não uma caixa de seleção

Uma partição de rede significa que os nós do cluster não podem todos conversar entre si. O RabbitMQ tem estratégias de manipulação de partições, mas nenhuma delas transforma uma rede quebrada em uma saudável. A resposta correta é projetar o cluster para que as partições sejam raras, visíveis e recuperadas com cuidado.

Para a maioria dos clusters de produção, use um número ímpar de nós para cargas de trabalho baseadas em quorum e evite esticar um cluster pequeno através de links não confiáveis. Três nós em três zonas de disponibilidade podem funcionar bem se a latência for aceitável. Dois nós divididos em dois sites é uma fonte comum de decisões dolorosas porque não há maioria se o link quebrar.

Após uma partição suspeita, verifique:

rabbitmqctl cluster_status
rabbitmq-diagnostics alarms
rabbitmq-diagnostics check_running
rabbitmqctl list_queues name type leader members online state

Se os líderes da fila se moveram ou membros ficaram offline, não assuma que a aplicação está bem porque as conexões se recuperaram. Observe as confirmações do publisher, taxas de erro do consumidor e mensagens não confirmadas.

Hábitos de manutenção que previnem surpresas no cluster

Drene as conexões antes de parar um nó quando possível. Se você colocar clientes atrás de um balanceador de carga, remova o nó da rotação, aguarde os clientes se reconectarem em outro lugar e então reinicie o RabbitMQ.

Verifique a distribuição de filas periodicamente:

rabbitmqctl list_queues name type leader messages consumers

Se todo líder de fila quente estiver em um nó, o cluster não está balanceado para essa carga de trabalho. Você pode precisar redeclarar filas, revisar políticas ou usar configurações de localizador de líder de fila apropriadas para sua versão do RabbitMQ.

Mantenha as políticas sob controle de versão. Uma política que altera o tipo de fila, dead-lettering, comprimento máximo ou comportamento de espelhamento é infraestrutura de produção, não um ajuste de UI.

Backups ainda importam. Clustering não é um substituto para exportação de definições, automação de infraestrutura ou planejamento de recuperação de desastres. Exporte definições após mudanças de topologia:

rabbitmqadmin export rabbitmq-definitions.json

Finalmente, teste a falha que você acha que pode sobreviver. Pare um nó que segura um líder de fila. Mate um consumidor enquanto ele tem mensagens não confirmadas. Bloqueie um publisher durante um alarme de disco em staging. Um cluster RabbitMQ ganha confiança através de ensaios chatos, não através de um diagrama com três nós nele.