Clustering RabbitMQ : Configuration, installation et bonnes pratiques
Découvrez la puissance de la messagerie scalable et résiliente avec le clustering RabbitMQ. Ce guide couvre les concepts essentiels comme les types de nœuds, les partitions réseau et la synchronisation des données. Apprenez étape par étape à configurer un cluster RabbitMQ, à configurer des files d'attente à haute disponibilité (HA) à l'aide de politiques et à mettre en œuvre les meilleures pratiques pour un déploiement et une gestion robustes. Parfait pour les développeurs et les opérateurs cherchant à créer des applications orientées messages tolérantes aux pannes.
Clustering RabbitMQ : Configuration, installation et bonnes pratiques
Le clustering RabbitMQ est souvent mal compris. Un cluster vous donne un seul courtier logique composé de plusieurs nœuds Erlang. Il partage les utilisateurs, les vhosts, les échanges, les liaisons, les politiques et autres métadonnées entre ces nœuds. Il ne rend pas automatiquement les messages de chaque file d'attente disponibles partout. La disponibilité des files d'attente dépend du type de file d'attente et de ses paramètres de réplication.
Cette différence compte en production. Un cluster peut faciliter la gestion et le routage, et peut prendre en charge des files d'attente hautement disponibles, mais ce n'est pas un interrupteur de performance magique. Si vous placez toutes les files d'attente chaudes sur un seul nœud, ce nœud fait toujours le travail. Si vous utilisez des files d'attente classiques sans réplication et que le nœud du leader de la file d'attente disparaît, cette file d'attente est indisponible jusqu'au retour du nœud. Concevez le cluster autour des files d'attente que vous exécutez réellement.
Ce qu'un cluster partage, et ce qu'il ne partage pas
Les métadonnées du cluster RabbitMQ sont répliquées. Si vous déclarez un échange sur un nœud, les autres nœuds le savent. Si vous ajoutez un utilisateur ou une politique, le cluster stocke cette définition. Les applications clientes peuvent se connecter à n'importe quel nœud et utiliser la même topologie.
Les messages sont différents. Une file d'attente a un leader. Pour les files d'attente classiques, les messages vivent sur le nœud qui héberge cette file d'attente, sauf si vous utilisez d'anciennes files d'attente mises en miroir. Pour les files d'attente quorum, RabbitMQ réplique les données de la file d'attente sur un groupe de nœuds en utilisant un protocole de consensus. Pour les flux, les données sont répliquées selon la configuration du flux. Dans les déploiements RabbitMQ modernes, les files d'attente quorum sont généralement le choix le plus sûr pour les files d'attente de travail durables et répliquées.
Les articles plus anciens parlent souvent de "files d'attente HA" comme si c'était la valeur par défaut moderne. Dans la terminologie RabbitMQ, cela signifie généralement des files d'attente classiques mises en miroir configurées par politique. Elles existent encore dans certaines installations, mais les files d'attente quorum sont la direction que la plupart des nouvelles conceptions de files d'attente durables répliquées devraient envisager. Vérifiez toujours la version de RabbitMQ et les contraintes opérationnelles de votre environnement avant de migrer une charge de travail existante.
Avant de joindre des nœuds
Faites d'abord les vérifications ennuyeuses :
- Les nœuds doivent résoudre les noms d'hôte des autres de manière cohérente.
- Le port de distribution Erlang et les ports RabbitMQ doivent être accessibles entre les nœuds.
- Les versions de RabbitMQ et Erlang doivent être compatibles dans tout le cluster.
- Tous les nœuds doivent partager le même cookie Erlang.
- La synchronisation temporelle doit être saine, surtout si votre surveillance et TLS en dépendent.
Le cookie Erlang est un secret partagé utilisé par les nœuds Erlang. Sur de nombreux paquets Linux, il se trouve à /var/lib/rabbitmq/.erlang.cookie, propriété de l'utilisateur rabbitmq et mode 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
Ne régénérez pas le cookie à la légère sur un cluster en cours d'exécution. Si un nœud a un cookie différent, il ne pourra pas communiquer avec les autres, et le message d'erreur n'est pas toujours convivial.
Joindre un nœud
Supposons que rabbit@rmq-a soit déjà en cours d'exécution et que rabbit@rmq-b doive le rejoindre. Sur rmq-b :
sudo rabbitmqctl stop_app
sudo rabbitmqctl reset
sudo rabbitmqctl join_cluster rabbit@rmq-a
sudo rabbitmqctl start_app
Vérifiez ensuite depuis n'importe quel nœud :
rabbitmqctl cluster_status
rabbitmq-diagnostics cluster_status
reset supprime la base de données RabbitMQ du nœud local avant de rejoindre. C'est généralement ce que vous voulez pour un nouveau nœud vide. Ce n'est pas quelque chose à exécuter à la légère sur un nœud qui possède des files d'attente qui vous tiennent à cœur.
Pour trois nœuds, répétez le même processus depuis rmq-c. Vous pouvez joindre à la fois rmq-b et rmq-c à rmq-a ; une fois joints, il n'y a pas de nœud "maître" permanent pour les métadonnées comme les gens l'imaginent parfois.
Mettez les clients derrière un point de terminaison stable
Les applications ne doivent pas avoir un seul hôte de courtier codé en dur si vous prévoyez une maintenance des nœuds. Utilisez un équilibreur de charge, une stratégie DNS ou une liste de connexion de bibliothèque cliente. L'équilibreur de charge doit vérifier si l'application RabbitMQ est en cours d'exécution, pas seulement si le port 5672 est ouvert.
Une simple vérification TCP peut envoyer les clients vers un nœud qui est vivant mais bloqué par des alarmes ou pas complètement joint. Dans des environnements plus stricts, utilisez des vérifications de santé exposées via le plugin de gestion ou une petite vérification locale qui exécute rabbitmq-diagnostics -q ping.
Choisissez les types de files d'attente délibérément
Pour les charges de travail durables répliquées, une file d'attente quorum est souvent un bon choix par défaut :
rabbitmqadmin declare queue name=orders.pending durable=true arguments='{"x-queue-type":"quorum"}'
Ou via la déclaration d'application :
channel.queue_declare(
queue='orders.pending',
durable=True,
arguments={'x-queue-type': 'quorum'}
)
Les files d'attente quorum échangent un certain débit et une certaine latence contre un comportement de réplication plus fort. Ce ne sont pas une mise à niveau gratuite pour chaque file d'attente. Pour les files d'attente de réponse temporaires, les abonnés fanout de courte durée ou les travaux transitoires de faible valeur, les files d'attente classiques peuvent convenir. Pour les événements métier qui doivent survivre à la perte d'un nœud, utilisez un type de file d'attente répliqué et testez le basculement.
Les partitions réseau sont un événement opérationnel, pas une case à cocher
Une partition réseau signifie que les nœuds du cluster ne peuvent pas tous se parler. RabbitMQ a des stratégies de gestion des partitions, mais aucune d'entre elles ne transforme un réseau cassé en un réseau sain. La bonne réponse est de concevoir le cluster pour que les partitions soient rares, visibles et récupérées avec soin.
Pour la plupart des clusters de production, utilisez un nombre impair de nœuds pour les charges de travail basées sur le quorum et évitez d'étirer un petit cluster sur des liaisons peu fiables. Trois nœuds répartis sur trois zones de disponibilité peuvent bien fonctionner si la latence est acceptable. Deux nœuds répartis sur deux sites est une source courante de décisions douloureuses car il n'y a pas de majorité si la liaison est rompue.
Après une partition suspectée, vérifiez :
rabbitmqctl cluster_status
rabbitmq-diagnostics alarms
rabbitmq-diagnostics check_running
rabbitmqctl list_queues name type leader members online state
Si les leaders des files d'attente ont bougé ou si les membres sont hors ligne, ne présumez pas que l'application va bien parce que les connexions ont récupéré. Surveillez les confirmations de publication, les taux d'erreur des consommateurs et les messages non acquittés.
Habitudes de maintenance qui évitent les surprises du cluster
Videz les connexions avant d'arrêter un nœud lorsque cela est possible. Si vous placez les clients derrière un équilibreur de charge, retirez le nœud de la rotation, attendez que les clients se reconnectent ailleurs, puis redémarrez RabbitMQ.
Vérifiez périodiquement la distribution des files d'attente :
rabbitmqctl list_queues name type leader messages consumers
Si chaque leader de file d'attente chaude se trouve sur un seul nœud, le cluster n'est pas équilibré pour cette charge de travail. Vous devrez peut-être redéclarer les files d'attente, revoir les politiques ou utiliser les paramètres de localisation du leader de file d'attente appropriés pour votre version de RabbitMQ.
Gardez les politiques sous contrôle de source. Une politique qui modifie le type de file d'attente, la mise en file d'attente des lettres mortes, la longueur maximale ou le comportement de mise en miroir est une infrastructure de production, pas un réglage d'interface utilisateur.
Les sauvegardes comptent toujours. Le clustering ne remplace pas l'exportation des définitions, l'automatisation de l'infrastructure ou la planification de la reprise après sinistre. Exportez les définitions après les changements de topologie :
rabbitmqadmin export rabbitmq-definitions.json
Enfin, testez la défaillance que vous pensez pouvoir survivre. Arrêtez un nœud qui détient un leader de file d'attente. Tuez un consommateur alors qu'il a des messages non acquittés. Bloquez un éditeur pendant une alarme de disque dans un environnement de test. Un cluster RabbitMQ gagne la confiance grâce à des répétitions ennuyeuses, pas grâce à un diagramme avec trois nœuds dessus.