Gérer votre cluster RabbitMQ

RabbitMQ est un excellent courtier de messages distribués, mais difficile à administrer par programme. Dans ce tutoriel, je vais vous montrer comment créer un cluster, ajouter des nœuds, supprimer des nœuds, démarrer et arrêter. En prime, je partagerai un fichier Fabric qui vous permettra de prendre le contrôle total. Le code est disponible sur GitHub.

Introduction rapide à RabbitMQ

RabbitMQ est une file de messages très populaire. Plusieurs producteurs peuvent envoyer des messages et ces derniers peuvent les utiliser de manière totalement découplée. RabbitMQ est très populaire pour plusieurs raisons:

  1. C'est rapide et robuste.
  2. C'est open source, mais il y a un support commercial si vous le voulez.
  3. Il fonctionne sur votre système d'exploitation.
  4. Il est activement développé.
  5. Il est testé au combat.

RabbitMQ est implémenté à Erlang, ce qui est un peu inhabituel, mais l'une des raisons pour laquelle il est si fiable.

Conditions préalables

Pour les besoins de ce tutoriel, je vais utiliser un cluster Vagrant local de trois nœuds. Si vous avez déjà trois machines disponibles (virtuelles ou non), vous pouvez les utiliser à la place. Faites attention aux ports et aux réseaux.

Installez VirtualBox

Suivez les instructions pour installer VirtualBox.

Installer vagabond

Suivez les instructions pour installer Vagrant

Créer un cluster RabbitMQ

Voici un fichier Vagrant qui créera un cluster local à trois nœuds sur votre ordinateur. Le système d'exploitation est Ubuntu 14.04 (Trusty).

ruby # - * - mode: ruby ​​- * - # vi: définir ft = ruby: hosts = "rabbit-1" => "192.168.77.10", "rabbit-2" => "192.168.77.11", "lapin -3 "=>" 192.168.77.12 " Vagrant.configure (" 2 ") do | config | config.vm.box = "trusty64" hosts.each_with_index do | (nom, ip), i | rmq_port = 5672 + i admin_port = 15672 + i config.vm.define nom do | machine | machine.vm.network: réseau_private, ip: ip config.vm.hostname = "rabbit-% d"% [i + 1] config.vm.network: port transféré, invité: 5672, pass_ip: ip, hôte: rmq_port config vm.network: forwarded_port, guest: 15672, guest_ip: ip, hôte: admin_port machine.vm.provider "virtualbox" do | v | v.name = nom fin fin fin fin

Pour créer un cluster vide, tapez: vagabond.

Configuration de SSH

Pour faciliter la connexion SSH aux nœuds du cluster, tapez: vagrant ssh-config >> ~ / .ssh / config.

Si vous tapez: cat ~ / .ssh / config, vous devriez voir les entrées pour lapins-1, lapins-2 et lapins-3.

Maintenant, vous pouvez ssh dans chaque machine virtuelle par nom: ssh lapin-1.

Assurez-vous que les nœuds sont accessibles par nom

Le moyen le plus simple consiste à modifier le fichier / etc / hosts. Par exemple, pour lapin-1, ajoutez les adresses de lapin-2 et du lapin-3..

uni 192.168.77.11 lapin-2 192.168.77.12 lapin-3

Répétez le processus pour tous les nœuds.

Installer RabbitMQ

Je vais utiliser apt-get ici pour les systèmes d'exploitation Debian / Ubuntu. Si votre cluster fonctionne sur un autre système d'exploitation, veuillez suivre les instructions de la page d'installation de RabbitMQ..

Notez que parfois une version plutôt obsolète de RabbitMQ est disponible par défaut. Si vous voulez installer les versions les plus récentes, vous pouvez télécharger directement un paquet .deb ou ajouter apt-repository de RabbitMQ, en utilisant ces instructions.

La version actuelle de RabbitMQ sur Ubuntu 14.04 est 3.2, ce qui est suffisant pour nos besoins. Vérifiez vous-même en tapant: apt-cache montre rabbitmq-server.

Allons-y et installons-le sur chaque machine:

sudo apt-get mise à jour sudo apt-get installer rabbitmq-server -y

N'hésitez pas à utiliser votre outil de gestion de la configuration préféré, comme Chef ou Ansible, si vous préférez..

Notez qu'Erlang sera d'abord installé en tant que condition préalable..

Activer le plugin de gestion RabbitMQ

Le plugin de gestion est vraiment cool. Il vous fournit une API basée sur HTTP, ainsi qu'une interface graphique Web et un outil de ligne de commande pour gérer le cluster. Voici comment l'activer:

sudo plain rabbitmq-plugins enable rabbitmq_management

Obtenir l'outil de ligne de commande de gestion

Téléchargez-le à partir de http://192.168.77.10:15672/cli/rabbitmqadmin. Notez que la documentation RabbitMQ est incorrecte et vous conseille de télécharger à partir de http: //: 15672 / cli /.

C'est un client HTTP basé sur Python pour l'API HTTP de gestion RabbitMQ. C'est très pratique pour écrire des clusters RabbitMQ.

Concepts de base de RabbitMQ

RabbitMQ implémente le standard AMQP 0.9.1 (Advanced Message Queue Protocol). Notez qu’il existe déjà une norme AMQP 1.0 et que RabbitMQ dispose d’un plugin pour la prendre en charge, mais il est considéré comme un prototype en raison d’une utilisation insuffisante dans le monde réel..

Dans le modèle AMQP, les éditeurs envoient des messages à un courtier de messages (RabbitMQ est le courtier de messages dans ce cas) via un échange. Le courtier de messages distribue les messages aux files d'attente en fonction des métadonnées associées au message. Les consommateurs consomment des messages de files d'attente. Les messages peuvent ou non être acquittés. RabbitMQ prend en charge une variété de modèles de programmation en plus de ces concepts, tels que les files d’attente, Publier-souscrire et RPC..

Gérer votre cluster

Trois scripts sont utilisés pour gérer le cluster. Le script rabbitmq-server démarre un serveur RabbitMQ (lancez-le). Rabbitmqctl est utilisé pour contrôler le cluster (arrêter, réinitialiser, regrouper les nœuds et obtenir le statut). Le rabbitmqadmin, que vous avez téléchargé précédemment, est utilisé pour configurer et administrer le cluster (déclarer les hôtes virtuels, les utilisateurs, les échanges et les files d'attente). La création d'un cluster implique uniquement rabbitmq-server et rabbitmqctl.

Tout d’abord, commençons par rabbitmq-server en tant que service (démon) sur chacun de nos hôtes rabbit-1, rabbit-2 et rabbit-3..

service sudo simple rabbitmq-server start

Cela démarrera à la fois la machine virtuelle Erlang et l'application RabbitMQ si le nœud est en panne. Pour vérifier qu'il fonctionne correctement, tapez:

sudo rabbitmqctl cluster_status

Le résultat devrait être (pour le lapin 1):

État de la grappe en clair du nœud 'rabbit @ rabbit-1'…… [nœuds, [disque, ['rabbit @ rabbit-1'],, run_nodes, ['rabbit @ rabbit-1'], partitions ,[]]… terminé.

Cela signifie que le nœud n'est pas encore en cluster avec d'autres nœuds et qu'il s'agit d'un nœud de disque. Il est également en cours d'exécution car vous pouvez voir qu'il apparaît dans la liste running_nodes.

Pour arrêter le serveur, lancez la commande suivante:

sudo rabbitmqctl stop_app

Ensuite, si vous vérifiez le statut du cluster:

sudo rabbitmqctl cluster_status

Le résultat devrait être:

État de la grappe en clair du nœud 'rabbit @ rabbit-1'…… [nœuds, [disc, ['rabbit @ rabbit-1']…….

Pas plus de nœuds en cours d'exécution.

Vous pouvez répéter le processus pour les autres nœuds (lapins 2 et 3) et voir qu'ils ne connaissent que leur personne..

Le biscuit d'Erlang

Avant de pouvoir créer un cluster, tous les nœuds du cluster doivent avoir le même cookie. Le cookie est un fichier utilisé par le moteur d’exécution Erlang pour identifier les nœuds. Il est situé dans /var/lib/rabbitmq/.erlang.cookie. Il suffit de copier le contenu du lapin 1 vers le lapin 2 et le lapin 3.

Regroupement de nœuds

Pour regrouper ces nœuds distincts dans un cluster cohérent, il faut un peu de travail. Voici la procédure:

  • Avoir un seul nœud en cours d'exécution (par exemple, rabbit-1).
  • Arrêtez un autre noeud (par exemple, le lapin 2).
  • Réinitialiser le noeud arrêté (lapin-2).
  • Cluster l'autre noeud sur le noeud racine.
  • Démarrer le noeud arrêté.

Faisons cela. ssh en rabbit-2 et exécutez les commandes suivantes:

sudo rabbitmqctl plain_app sudo rabbitmqctl réinitialiser sudo rabbitmqctl join_cluster rabbit @ rabbit-1

Maintenant tapez: sudo rabbitmqctl cluster_status.

Le résultat devrait être:

"statut de groupe simple du noeud 'rabbit @ rabbit-2'…… noeuds, [disque, ['rabbit @ rabbit-1', '', 'rabbit @ rabbit-2']]]… Fait. Comme vous pouvez le voir les deux nœuds sont maintenant en cluster. Si vous répétez ceci sur le lapin 1, vous obtiendrez le résultat suivant:

Statut de la grappe du nœud 'rabbit @ rabbit-1'… [nœuds, [disque, ['rabbit @ rabbit-1', Rabbit @ rabbit-2 '',, 1 '], partitions, []]… terminé. "

Maintenant, vous pouvez commencer Rabbit-2.

sudo rabbitmqctl start_app

Si vous vérifiez à nouveau l'état, les deux nœuds seront en cours d'exécution:

statut de cluster simple du nœud 'rabbit @ rabbit-2'…… nœuds, [disque, ['rabbit @ rabbit-1', Rabbit @ rabbit-2 ']]], running_nodes, [' rabbit @ rabbit -1 ',' rabbit @ rabbit-2 '], partitions, []]… terminé.

Notez que les deux nœuds sont des nœuds de disque, ce qui signifie qu'ils stockent leurs métadonnées sur le disque. Ajoutons Rabbit-3 en tant que nœud RAM. ssh à lapin-3 et émettez les commandes suivantes:

sudo rabbitmqctl stop_app sudo rabbitmqctl réinitialiser sudo rabbitmqctl join_cluster --ram rabbit @ rabbit-2 sudo rabbitmqctl start_app

Vérification de l'état montre:

état de cluster simple du nœud 'rabbit @ rabbit-3'…… nœuds, [disque, ['rabbit @ rabbit-2', 'rabbit @ rabbit_1', 'rabbit @ rabbit-1']], ']], running_nodes, [' rabbit @ rabbit-1 ',' rabbit @ rabbit-2 ',' rabbit @ rabbit-3 '], partitions, []]… terminé.

Tous les nœuds de cluster sont en cours d'exécution. Les nœuds Disc sont les lapins 1 et 2, et le nœud RAM, le lapin 3..

Toutes nos félicitations! Vous avez un cluster de travail RabbitMQ.

Complications du monde réel

Que se passe-t-il si vous souhaitez modifier la configuration de votre cluster? Vous devrez utiliser la précision chirurgicale lors de l'ajout et de la suppression de nœuds du cluster..

Que se passe-t-il si un nœud n'est pas encore redémarré, mais que vous essayez de continuer? stop_app, réinitialiser et start_app? Eh bien, la commande stop_app va apparemment réussir, renvoyant «done», même si le nœud cible est en panne. Cependant, la commande de réinitialisation suivante échouera avec un message désagréable. J'ai passé beaucoup de temps à me gratter la tête pour essayer de comprendre, parce que je pensais que le problème était une option de configuration qui affectait uniquement la réinitialisation..

Un autre piège est que si vous voulez réinitialiser le dernier nœud du disque, vous devez utiliser force_reset. Essayer de trouver dans le cas général quel nœud était le dernier nœud du disque n’est pas trivial.

RabbitMQ prend également en charge le clustering via des fichiers de configuration. Cela est très utile lorsque vos noeuds de disque sont actifs, car les noeuds RAM redémarrés se regroupent simplement en fonction du fichier de configuration sans que vous ayez à les mettre en cluster de manière explicite. Encore une fois, il ne vole pas lorsque vous essayez de récupérer un cluster endommagé.

Clustering RabbitMQ fiable

Cela revient à ceci: vous ne savez pas quel a été le dernier nœud de disque à descendre. Vous ne connaissez pas les métadonnées de regroupement de chaque nœud (peut-être que la réinitialisation a eu lieu). Pour démarrer tous les nœuds, j'utilise l'algorithme suivant:

  • Démarrer tous les nœuds (au moins le dernier nœud du disque doit pouvoir démarrer).
  • Si même un seul nœud ne peut démarrer, vous êtes fatigué. Juste renflouer.
  • Gardez une trace de tous les nœuds dont le démarrage a échoué.
  • Essayez de démarrer tous les nœuds en panne.
  • Si certains nœuds ne parviennent pas à démarrer la deuxième fois, vous êtes affecté. Juste renflouer.

Cet algorithme fonctionnera tant que votre dernier nœud de disque est physiquement OK.

Une fois que tous les nœuds de cluster sont en place, vous pouvez les reconfigurer (souvenez-vous que vous ne savez pas quelles sont les métadonnées de cluster de chaque nœud). La clé est de forcer_reset chaque nœud. Cela garantit que toute trace de la configuration de cluster précédente est effacée de tous les nœuds. Commencez par le faire pour un nœud de disque:

plain stop_app force_reset start_app

Ensuite, pour chaque autre noeud (disque ou RAM):

plain stop_app force_reset join_cluster [liste des noeuds de disque] start_app

Contrôler un cluster à distance

Vous pouvez créer un répertoire SSH dans chaque zone et effectuer les étapes mentionnées ci-dessus manuellement. Cela fonctionne, mais il vieillit très vite. En outre, il n’est pas pratique de créer et de supprimer un cluster dans le cadre d’un test automatisé..

Une solution consiste à utiliser Fabric. Un problème sérieux que j'ai rencontré est que lorsque j'ai exécuté manuellement l'algorithme de construction de cluster, cela fonctionnait parfaitement, mais lorsque j'ai utilisé Fabric, cela a échoué de manière mystérieuse. Après un certain débogage, j'ai remarqué que les noeuds avaient démarré avec succès, mais au moment où j'ai essayé d'arrêter stop_app, les noeuds étaient en panne. Cela s'est avéré être une erreur de débutant de tissu de ma part. Lorsque vous émettez une commande à distance à l'aide de Fabric, un nouveau shell est lancé sur la machine distante. Lorsque la commande est terminée, le shell est fermé et envoie un signal SIGHUP (signal de raccrochage) à tous ses sous-processus, y compris le nœud Erlang. Utiliser nohup s'en occupe. Une autre option plus robuste consiste à exécuter RabbitMQ en tant que service (démon)..

Administration d'un cluster par programme

Administration signifie créer des hôtes virtuels, des utilisateurs, des échanges et des files d'attente, définir des autorisations et lier des files d'attente à des échanges. Si vous ne l’avez pas déjà fait, la première chose à faire est d’installer les plugins de gestion. Je ne sais pas pourquoi vous devez l'activer vous-même. Il devrait être activé par défaut.

L'interface utilisateur Web est fantastique et vous devez absolument vous familiariser avec elle. Toutefois, pour administrer un cluster à distance, vous pouvez utiliser une API de gestion RESTful. Il existe également un outil de ligne de commande Python appelé rabbitmqadmin qui nécessite Python 2.6+. Utiliser rabbitmqadmin est assez simple. Le seul problème que j'ai constaté est que je ne pouvais utiliser que le compte d'invité par défaut pour administrer le cluster. J'ai créé un autre utilisateur administrateur appelé "admin", défini ses autorisations à tous (configuration / lecture / écriture) et lui ai attribué la balise "administrateur" (exigence supplémentaire de l'API de gestion), mais j'ai continué à avoir des erreurs d'autorisation..

Le projet Elmer vous permet de spécifier une configuration de cluster en tant que structure de données Python (voir sample_config.py) et de tout configurer à votre place..

Points à emporter

  1. RabbitMQ est cool.
  2. L'histoire d'administrateur de cluster n'est pas étanche.
  3. L'administration programmatique est la clé.
  4. Fabric est un outil génial pour contrôler à distance plusieurs boîtes Unix..