Rabbitmq est l’une des solutions de message queue les plus connues au niveau mondial. Sa simplicité d’installation et de compréhension le rend très facile à déployer et mettre en place en entreprise.
Devenez un dompteur
de lapin !!!
Je vous propose une brève introduction à Rabbitmq et vous pourrez continuer votre autoformation en consultant la page regroupant l’ensemble des tutoriels. Et vous pourrez également retrouver les slides et codes proposés dans cette autoformation ici sur gitlab.
Rabbitmq, c’est quoi ??
Rabbitmq est une technologie qui a fait ses preuves. Créée en 2007, elle a fait l’objet de rachats par la suite pour finir par être rattachée à vmware.
Son principe historique repose sur la connexion entre des producers et des consumers de messages. Historiquement, Rabbbimq utilise le principe de First In First Out (FIFO). Les messages sont donc consommés dans le même ordre d’où ils ont été produit (hors exception lors de quorum queues ou de sharding c’est à dire lorsque les messgaes sont déposés dans des queues partitionnées).
L’explosion des infrastructures à base de microservices mais surtout la volonté de rendre les infrastructures asynchrones et permettant de scaler facilement (augmenter/diminuer sans délai le nombre de consumers ou de producers). de fait la possibilité d’accroitre facilement le nombre de ces instances, permet aussi de plus facilement réaliser leurs maintenances.
Bien sûr, Rabbitmq lui-même est un système redondé et distribué, permettant aussi d’assurer facilement les upgrades et autres tâches à réaliser pour maintenir un cluster.
En outre Rabbitmq permet de travailler avec plusieurs protocoles d’échanges de messages :
* AMQP : Advanced Message Queuing Protocol (diff langages C/P) * STOMP : Streaming Text Oriented Message Protocol (sous TCP) * MQTT : Message Queuing Telemetry Transport (pub/sub léger, IoT) * HTTP : Hypertext Transfer Protocol
Par ailleurs, comme tout bon outil opensource, il dispose d’une communauté. Vous pourrez facilement retrouver des informations sur les sites de questions réponses habituels : stackoverflow & reddit. Ou encore, la communauté permet de développer des plugins permettant d’augmenter les cas d’usages et de facilité l’utilisation de l’application.
Quelques notions, définitions et concepts avant de commencer
Broker : serveur portant une instance rabbitmq au sein d’un cluster (ensemble de brokers)
Consumer : consommateur de messages après connexion à une queue
Messages : ordonnés ou non, sont composés de metadatas et de données
Channel : élément permettant la connexion des producteurs pour recueillir les messages. Permet de gérer les connexions par multiplexage (plusieurs connexions en une).
Exchange : recueille les messgaes de producteur et a la charge de les router suivant le type d”exchange et de binding. C’est le coeur de l’intelligence de la répartition des messages entrant vers les queues rabbitmq.
Binding : connexion d’un exchange avec une queue.
Queue : ensemble de message avec plus ou moins de haute disponibilité.
Vhosts : il s’agit d’une couche logique permettant l’isolation de tous les objets au sein de rabbitmq (hormis les utilisateurs) et de gérer les droits et permissions.
Routing key : élément du message pris en compte pour filtrer et router les messages au sein d’un exchange.
En résumé :
Producer > Channel > Exchange > Binding > Routing Key > Queue > Consumer
Comment installer son premier cluster Rabbitmq ?
Pour notre exemple, nous partirons sur 3 serveurs (vm debian). Compte tenu du protocole d’élection de certains éléments permettant la haute disponibilité (comme les quorum queues), il est préférable de toujours avoir un nombre impair de brokers.
Commençons par installer erlang (langage dans lequel est développé rabbitmq) et rabbitmq en fichier .deb.
sudo apt install erlang-nox wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.13/rabbitmq-server_3.9.13-1_all.deb sudo dpkg -i rabbitmq-server_3.9.13-1_all.deb rabbitmq-plugins enable rabbitmq_management
Et vous l’avez peut être remarqué, nous avons également installé un plugin rabbitmq_management qui va nous permettre d’administrer le cluster.
Puis un à un sur chaque serveur nous allons ajouter un token d’identification de notre cluster alias le erlang cookie.
echo "YOATBIGKDHUSBLUSTOAW" | sudo tee /var/lib/rabbitmq/.erlang.cookie echo "listeners.tcp.1 = 0.0.0.0:5672" | sudo tee -a /etc/rabbitmq/rabbitmq.conf echo "management.tcp.port = 15672" | sudo tee -a /etc/rabbitmq/rabbitmq.conf systemctl restart rabbitmq-server
Nous en avons profité également pour permettre l’écoute sur toutes les interfaces réseau du port 5672 c’est le port de communication entre un client et rabbitmq. Et également sur le port 15672 qui est celui de l’interface graphique de rabbitmq.
Pour les autres serveurs voici les commandes à lancer :
rabbitmqctl stop_app rabbitmqctl join_cluster rabbit@rmq1 rabbitmqctl start_app
On stop le service rabbitmq au sein de erlang, on demande au serveur de rejoindre le premier serveur et on démarre l’instance de nouveau.
Enfin pour vérifier la présence de nos brokers au sein du même cluster, nous pouvons lancer un cluster_status.
rabbitmqctl cluster_status --formatter=json | jq -r .running_nodes[]
Et voilà notre premier cluster rabbitmq.
Créer notre premier utilisateur
Tout simplement pour vérifier le bon fonctionnement de notre cluster, nous allons créer notre premier utilisateur :
rabbitmqctl add_user xavki password
rabbitmqctl set_permissions -p / xavki ".*" ".*" ".*"
rabbitmqctl set_user_tags xavki administrator
Et voilà maintenant on à un user xavki avec les droits d’administration de notre cluster. Il ne reste plus qu’à se connecter avec votre navigateur : http://<ip>:15672
Et maintenant un cluster rabbitmq avec un provisionning Vagrant (Vagrantfile)
Je ne vais pas commenter ici les fichiers en question mais nous en avons 2.
D’une part le vagrantfile qui va permettre de provisionner les machines et d’autre part un script shell lancé par vagrant (cf dans le vagrantfile).
Vagrant.configure(2) do |config| # before you must install these plugins to speed up vagrant provisionning # vagrant plugin install vagrant-faster # vagrant plugin install vagrant-cachier config.cache.auto_detect = true # Set some variables etcHosts = "" rabbitmq = "" # Check ingress controller case ARGV[0] when "provision", "up" print "Do you want to install rabbitmq (yes/no) ?\n" rabbitmq = STDIN.gets.chomp print "\n" end # some settings for common server (not for haproxy) common = <<-SHELL sudo apt update -qq 2>&1 >/dev/null sudo apt install -y -qq curl git vim tree net-tools telnet git python3-pip sshpass nfs-common 2>&1 >/dev/null sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config sudo systemctl restart sshd SHELL config.vm.box = "debian/bullseye64" config.vm.box_url = "debian/bullseye" # set servers list and their parameters NODES = [ { :hostname => "rmq1", :ip => "192.168.12.48", :cpus => 2, :mem => 2048, :type => "rmq_leader" }, { :hostname => "rmq2", :ip => "192.168.12.49", :cpus => 2, :mem => 2048, :type => "rmq_follower" }, { :hostname => "rmq3", :ip => "192.168.12.50", :cpus => 2, :mem => 2048, :type => "rmq_follower" } ] # define /etc/hosts for all servers NODES.each do |node| etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + "'>> /etc/hosts" + "\n" if node[:type] == "gitlab" etcHosts += "echo '" + node[:ip] + " " + gitlabUrl + " registry." + gitlabUrl + "' >> /etc/hosts" + "\n" end end #end NODES # run installation NODES.each do |node| config.vm.define node[:hostname] do |cfg| cfg.vm.hostname = node[:hostname] cfg.vm.network "private_network", ip: node[:ip] cfg.vm.provider "virtualbox" do |v| v.customize [ "modifyvm", :id, "--cpus", node[:cpus] ] v.customize [ "modifyvm", :id, "--memory", node[:mem] ] v.customize [ "modifyvm", :id, "--natdnshostresolver1", "on" ] v.customize [ "modifyvm", :id, "--natdnsproxy1", "on" ] v.customize [ "modifyvm", :id, "--name", node[:hostname] ] v.customize [ "modifyvm", :id, "--ioapic", "on" ] v.customize [ "modifyvm", :id, "--nictype1", "virtio" ] end #end provider #for all cfg.vm.provision :shell, :inline => etcHosts cfg.vm.provision :shell, :inline => common if rabbitmq == "yes" if node[:type] == "rmq_leader" cfg.vm.provision :shell, :path => "install_rabbitmq.sh", :args => "leader" end if node[:type] == "rmq_follower" cfg.vm.provision :shell, :path => "install_rabbitmq.sh", :args => "follower" end end end # end config end # end nodes end
Maintenant le script bash d’installation de rabbitmq install_rabbitmq.sh :
#!/bin/bash ## install rabbitmq IP=$(hostname -I | awk '{print $2}') echo "START - install rabbitmq "$IP echo "[1]: install erlang-nox & utils" apt-get update -qq >/dev/null apt-get install -qq -y wget unzip dnsutils erlang-nox >/dev/null echo "[2]: install rabbitmq" wget -q https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.13/rabbitmq-server_3.9.13-1_all.deb dpkg -i rabbitmq-server_3.9.13-1_all.deb echo "[3]: minimal configuration" rabbitmq-plugins enable rabbitmq_management echo "YOATBIGKDHUSBLUSTOAW" | sudo tee /var/lib/rabbitmq/.erlang.cookie echo "listeners.tcp.1 = 0.0.0.0:5672" | sudo tee -a /etc/rabbitmq/rabbitmq.conf echo "management.tcp.port = 15672" | sudo tee -a /etc/rabbitmq/rabbitmq.conf systemctl restart rabbitmq-server if [[ "$1" == "leader" ]]; then echo "[4]: define default user" rabbitmqctl add_user xavki password rabbitmqctl set_permissions -p / xavki ".*" ".*" ".*" rabbitmqctl set_user_tags xavki administrator rabbitmqctl delete_user guest fi if [[ "$1" == "follower" ]]; then echo "[4]: join leader" rabbitmqctl stop_app rabbitmqctl join_cluster rabbit@rmq1 rabbitmqctl start_app fi
Et donc un petit coup de vagrant up et vous aurez un clsuter rabbitmq à la sortie. Idéal pour faire des tests et se former je trouve.
Si tout cela vous a plus et si vous voulez m’aider, vous pouvez liker, partager et commenter les vidéos. Ou simplement un petit coup de main pour faire connaître la chaine Xavki au plus grand nombre (à la machine à café, autour d’une bière ou autre…).
Prenez plaisir et apprenons ensemble.