5 mars 2015

RabbitMQ - Serveur AMQP


RabbitMQ est un serveur Open Source produit par Pivotal qui permet de gérer des files de messages (Message Broker) pour l'échange d'informations entre des applications différentes sur des plate-formes différentes.

Il s'appuie sur le protocole AMQP qui veut dire Advanced Message Queuing Protocol.

AMQP est un protocole ouvert pour les systèmes orientés messages (MOM : Message-Oriented Middleware).

=> Voir la documentation de RabbitMQ sur les concepts AMQP

Installation de RabbitMQ - via l'installeur Windows

RabbitMQ nécessite Erlang pour fonctionner.

Pour installer Erlang :
  • Aller sur la page suivante pour télécharger Erlang 
  • Sur Windows:
    • Télécharger l’installeur via le lien OTP 17.4 Windows 64-bit Binary File
    • Lancer et terminer l’installation
Pour installer RabbitMQ :
  • Aller sur la page suivante pour télécharger RabbitMQ :
  • Sur Windows: 
    • Télécharger l’installeur rabbitmq-server.exe
    • Lancer et terminer l’installation

Installation de RabbitMQ - via Docker et Vagrant

Ce type d'installation nécessite que Vagrant et Virtualbox soient installés.

  • Créer un répertoire vide
  • Créer un fichier nommé Vagrantfile avec le contenu suivant:
  • Créer le sous-répertoire docker
  • Créer le fichier docker-compose.yml dans le sous-répertoire docker avec le contenu suivant:
Nous démarrons la VM avec Vagrant puis RabbitMQ avec docker :
  • Démarrer la VM avec Vagrant:
  • vagrant up
  • Accéder à la VM en SSH:
  • vagrant ssh
  • Dans la VM, passer en root:
  • sudo su
  • Lancer RabbitMQ via Docker:
  • cd docker
    docker-compose up -d
  • Aller sur la page suivante pour voir la console d'administration de RabbitMQ:

Démarrer / Arrêter RabbitMQ

Pour démarrer RabbitMQ:
  • Aller dans le menu Démarrer de Windows
  • Rechercher "RabbitMQ"
  • Cliquer sur RabbitMQ Service - start
Pour arrêter RabbitMQ:
  • Cliquer sur RabbitMQ Service - stop

Console d'administration

La console est disponible via le plugin : rabbitmq_management

Pour activer le plugin :

  • Ouvrir un terminal de commandes
  • Aller dans le répertoire sbin de RabbitMQ :
    • RabbitMQ Server/rabbitmq_server-3.4.4/sbin
  • Lancer la commande suivante :
    • sous Windows : ./rabbitmq-plugins.bat enable rabbitmq_management
    • sur Linux : rabbitmq-plugins enable rabbitmq_management
  • Aller sur l'URL :
  • Liste des connexions :
  • Liste des files de messages : 


Utilisation de RabbitMQ en JAVA

Le client JAVA pour RabbitMQ est un client qui permet de s'interfacer avec des serveurs AMQP.
Dépendance Maven :
<dependency>
  <groupId>com.rabbitmq</groupId>
  <artifactId>amqp-client</artifactId>
  <version>3.4.4</version>
</dependency>
Documentation du client JAVA :

Test simple avec envoi et réception d'un message

Nous sommes dans le cas d'utilisation où le producteur envoie le message "Hello World!" sur la file de messages pour qu'il soit lu par le consommateur :

La classe de test suivante effectue les étapes suivantes :

  • Connexion à RabbitMQ
  • Création d'un canal
  • Déclaration d'une file de messages
  • Déclaration d'un consommateur
  • Envoi d'un message sur la file de messages
  • Le consommateur récupère le message présent dans la file des messages
  • Le canal et la connexion sont fermés

Avec deux classes Producer et Consumer

  • Producer :

  • Consumer :

Message

Un message AMQP contient:
  • un corps:
    •  bodybyte[] 
  • des propriétés :
    • headersMap<String, Object>
      • en-tête du message
      • permet de mettre des valeurs pour le routage des messages entre les files de message quand le Exchange est en mode "headers"
    • routing_key:
      • clé pour le routage du message sur les files de messages par l'Exchange si celui-ci est en mode "direct" ou "topic"
    • content-type
      • format du contenu
      • ex: JSON
    • content-encoding
      • encodage des caractères
      • ex: UTF-8
    • etc.

Diffusion de messages: utilisation du Exchange

Le Exchange permet la diffusion de messages sur plusieurs files de messages.
En pratique, un producteur "P" envoie un message à l'Exchange et celui-ci diffuse ce message sur des files de messages.

Il existe 4 modes de Exchange :

Mode Exchange: fanout

  • fanout: le message est diffusé sur toutes les files de messages
    • Aucune condition de routage

Mode Exchange: direct

  • direct: le message est diffusé sur une liste déterminée de files de messages en fonction de la clé de routage routing_key:
    • Les files de message ont la propriété routing_key
    • A l'envoi d'un message, on indique la clé de routage routing_key afin de sélectionner la ou les files de messages sur lesquelles envoyer le message

Mode Exchange: topic

  • topic: le message est diffusé sur des files de messages en fonction de plusieurs critères indiquées dans la clé de routage routing_key :
    • Les valeurs des critères sont concaténées dans une seule chaîne de caractères nommée routing. Ces valeurs sont séparées par ":"
      • Exemple : valeur1:valeur2:valeur3 pour <quantity>:<color>:<element>
    • File de messages:
      • La clé de routage routing_key contient pour chaque critère une valeur ou un joker "*"
        • Exemple:
          • File A: *:blue:fish
          • File B10:green:*
          • File C: *:red:*
    • Message:
      • La clé de routage routing_key contient les valeurs pour chaque critère
        • Exemple: 
          • Le message avec : 3:blue:fish sera envoyé sur la File A par l'Exchange.

Mode Exchange: headers

  • headers: les messages sont diffusés sur certaines files de messages en fonction des valeurs des attributs de l'en-tête du message.
    • Ce mode est plus pratique que le mode topic car on défnit les valeurs dans les attributs de l'en-tête du message plutôt que de les concaténer dans la clé de routage routing_key
    • File de message:
      • on indique les valeurs des attributs pour la sélection des messages
    • Message:
      • les valeurs sont définies dans les attributs de l'en-tête du message

Tutoriel officiel de RabbitMQ

Notions:
  • Producteur (producer): Il transmet le message à la file de messages en indiquant le ou les destinatires qui seront consommateurs de ce message
  • File de message (queue): La file stocke les messages (boîte aux lettres). Il peut y avoir plusieurs files de messages.
  • Consommateur (consumer): Il est en attente de réception de messages et il traite (consomme) les messages qui lui sont addressés

Envoi / Réception d'un message

  • Le producteur "P" envoie un message "Hello World!" dans la file de message afin que ce message soit récupéré par le consommateur "C".

Work Queues

  • Au lieu d'envoyer des messages, le producteur "P" envoie des tâches qui seront effectuées par un des consommateurs C1 ou C2 non actuellement occupé à traiter une des tâches.
  • La répartition des tâches se fait de façon naturelle entre les consommateurs: dès que le consommateur termine une des tâches, il peut traiter la tâche suivante présente dans la file des messages.

Publish / Subscribe

  • Le principe cette fois-ci est que le message envoyé par le producteur "P" est dupliqué et dispatché par "X" sur l'ensemble des files de messages. Ce message est ainsi diffusé aux consommateurs abonnés à ces flux de messages. Ainsi plusieurs consommateurs vont recevoir ce message. Ce pattern est appelé "publish/subscribe".

Routing

  • Les messages sont diffusés sur certaines files de messages. Ainsi les consommateurs ne traitent qu'un certain type de messages.
  • L'exemple ici est de répartir la diffusion des messages de logs en fonction du niveau de log : 
    • C1 va traiter les messages "error",
    • C2 peut traiter l'ensemble des messages de log: "error", "info", "warning".

Topics

  • L'objectif est de répartir les messages en fonction de plusieurs critères. Les valeurs sont concaténées dans une seule chaîne de caractères "critère1:critère2:critère3". Des expressions utilisant des jokers permettent de sélectionner certaines valeurs pour chacun des critères : exemple : "*.*.blue".
  • Lien vers le tutoriel: Topics

Remote Procedure Call - RPC


  • Le client envoie un message de requête au serveur et ce client attend en retour le message de réponse de ce serveur.
  • Un identifiant unique correlationId sert au client pour faire l'association entre le message de requête au serveur et le message en réponse à cette requête.

Références