Blog Zenika

#CodeTheWorld

Java

Introduction à RabbitMQ – AMQP Partie I

RabbitMQ est un broker de messages se basant sur le standard AMQP afin d’échanger avec différents clients.
Cette suite d’article présente AMQP, RabbitMQ ainsi que l’API de Spring pour établir des connections vers un broker AMQP.

AMQP

Le protocole AMQP sur lequel est basé RabbitMQ a pour but d’offrir un système d’échange totalement interopérable entre les différents acteurs. Contrairement à JMS, AMQP n’est pas une API, et de fait ne consiste pas une librairie pour une plateforme en particulier, mais est un protocole d’échange tel que HTTP ou SMTP.
AMQP tire son origine du besoin de normer un système d’échanges de messages totalement asynchrone qui de plus s’abstrait totalement de l’implémentation du broker ou du client. En d’autres termes, il est tout à fait possible d’utiliser un broker AMQP en Erlang, sur lequel un client java va envoyer des messages qui seront consommés par un second client en .Net :
Global.png

Etablir la connection

AMQP table sur certains concepts pour gérer toute la communication entre les clients et le broker:
Un client va établir une connection (connection) vers le broker.
Au travers de cette connection, il pourra ouvrir un ou plusieurs channels (canaux) de communication grâce auxquels les requêtes pourront être transmises au broker, en parallèle.
Connection.png
Généralement, une application ne nécessite que l’ouverture d’une unique connexion; toute les communications sont ensuite effectuées au travers de plusieurs channels différents pendant la durée de vie de l’application.

Les bases d’un échange

Une fois connecté, un client va pouvoir accéder aux exchanges (échanges) et aux queues (files) pour transmettre et recevoir les messages.
L’exchange est le point où un message peut être déposé ; de là, le message suivra ensuite un cheminement pour enfin être placé dans la ou les queues de destination, où il sera entreposé jusqu’à consommation. Plusieurs client différents pourront envoyer des messages sur un même exchange, ainsi plusieurs messages envoyés pourront suivre le même mapping.
Le chemin pris par le message sera défini grâce aux bindings (liaisons) que l’on pourra appliquer entre un exchange et une queue. Ainsi il sera possible de définir la destination d’un message directement depuis le broker.
Ce système permet d’avoir un client producteur de messages indépendant du consommateur ; ainsi, en cas de changement d’architecture, il suffira de modifier les bindings adéquats sur le broker, les deux clients (producteur et consommateur) ne nécessitent alors pas de modification dans le code.
La queue est le point de consomation des messages; tout comme pour les exchanges, il est possible d’avoir plusieurs consommateurs sur une même queue.
Chaque consommateur peut demander au broker de lui envoyer le prochain message stocké dans la queue. Dès lors le message est envoyé au client et supprimé de la queue. Un message consommé n’est plus disponible, et de fait ne peut pas être consommé à nouveau.
Afin de simplifier les schémas, un client producteur de message sera symbolisé par Producer.png; un client consommateur de messages sera signalé par Consumer.png; un exchange par Exchange.png et une queue grâce à Queue.png

Premiers échanges (mode Fanout)

Le cas le plus basique est l’envoi d’un message sur un exchange désservant une queue particulière, et la consommation sur cette queue par un unique client.
Classic.png
Il est aussi possible d’envoyer le même message sur deux queues différentes afin que deux consommateurs puissent le recevoir et le traiter. A ce moment là le message est dupliqué, et chaque queue contient sa propre copie.
Fanout.png
Une autre variante consiste à déclarer plusieurs exchanges qui envoient des messages sur une queue commune.
Fanout2.png
Ici les messages reçus sur Exchange1 ou Exchange2 seront tous disponibles sur Queue2
Ce type d’échange est appelé fanout et représente une communication 1:N. Pour un exchange donné, les N queues liées pourront recevoir le message.

Utilisation des routing keys (mode Direct)

Afin de personnaliser les directions prises par un message, un système de binding/routing key est disponible. Chaque binding pourra définir sa propre binding key qui sera une chaîne de caractère identifiant un mapping précis. Les messages pourront de leur côté définir une routing key qui servira à définir au travers de quel binding le message devra passer. Une routing key est simplement un identifiant écrit sous la forme de noms séparés par des points. Par exemple si l’on devait représenter une key pour l’indice VMW, elle pourrait être sous la forme stock.us.vmw.
La routing key sera comparée aux binding keys de chaque binding disponible; si l’un correspond alors le message sera transféré uniquement sur la queue représentée dans ce binding.
Dans le cas ou la routing key ne correspondrait à aucune des possibilités, alors le message serait simplement ignoré.
Direct.png
Un message ayant la Routing key stock.us.vmw serait disponible sur Queue1 uniquement.
Comme auparavant il est possible d’ajouter d’autres acteurs pour augmenter les possibilités de la structure.
Les échanges de ce type sont appelés direct, ils permettent de mettre en place une communication 1:1. Pour un exchange donné, uniquement la queue dont le binding correspond à la routing key du message pourra recevoir le message.

Les wildcards (mode Topic)

Ce même système de routing/binding key est poussé au point de permettre d’utiliser des wildcards dans les noms des clefs.
Le premier type de wildcard, l’astérisque, permet de représenter un seul et unique élément dans la routing-key.
Par exemple une binding key stock.us.* pourrait représenter toutes les routing-key commençant par stock.us. et se terminant par un unique élément. Par exemple stock.us.vmw et stock.us.orcl seraient valides, stock.us.orcl.java ne le serait pas.
Un second caractère de wildcard, le dièse, est utilisable pour représenter une suite de plusieurs éléments.
Par exemple la binding key stock.# peut représenter stock.us.vmw, stock.us.orcl.java ou stock.fr.ead.
Topic.png
Dans cette configuration un message dont la routing key serait stock.us.orcl.java serait disponible dans Queue1 et Queue2.
Un message dont la routing key serait stock.fr.ead ne serait disponible que dans la Queue2.
Si le message avait une routing key non représentée dans les bindings, tel que fr.cac.ead, alors le message serait ignoré et ne figurerait dans aucune queue.
Les différents wildcards peuvent figurer n’importe ou dans la binding key; stock.#.orcl est donc elle aussi valide.
Ce système d’exchange est appelé le mode topic, il permet de mettre en place un échange en 1:N basé sur des règles définies dans les binding keys.

Conclusion

AMQP est un système très souple qui en plus de sa capacité à être utilisé dans n’importe quel environnement, gère la communication avec simplicité grâce aux différents systèmes d’échanges applicables.
Dans un prochain post, nous pourrons voir plus de détails le fonctionnement de AMQP: Comment définir le système d’échange utilisé, quelles sont les options disponibles pour les exchanges et queues, qui crée tous ces composants, etc.

4 réflexions sur “Introduction à RabbitMQ – AMQP Partie I

  • Perez

    Avec la partie II de l’article, cela fait un superbe article d’introduction à RabbitMQ!
    En attendant des articles additionnels: bravo!

    Répondre
  • Gunfire

    Sur les wildcards:
    « Dans cette configuration un message dont la routing key serait stock.us.orcl.java serait disponible dans Queue1 et Queue2 ». Dans Queue2 (stock.# ) et non dans Queue1 (stock.us.*)
    Sinon bravo

    Répondre
  • Merci pour l’article, je me dirige vers le second niveau.
    Ce qui manque pour des versions futures c’est peut être une approche fonctionnelle : des exemples d’utilisations types et aussi quand il ne faut pas l’utiliser. Enfin très bonnes bases en tout cas.

    Répondre
  • Merci bc pour cet article, une bonne introduction de rabbitmq

    Répondre

Répondre à PerezAnnuler la réponse.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

En savoir plus sur Blog Zenika

Abonnez-vous pour poursuivre la lecture et avoir accès à l’ensemble des archives.

Continue reading