Une introduction à RabbitMQ – Qu’est-ce que RabbitMQ ?

Pourquoi Rabbit ? Qu’est-ce que MQ ? Comment peut-il améliorer nos applications ? Pourquoi voudrais-je en apprendre davantage à son sujet ? – Ce sont les questions que je me suis posées lorsque j’ai été présenté pour la première fois à RabbitMQ. Je m’appelle Gabor, et je suis maintenant ingénieur et consultant RabbitMQ. Au cours de mon travail avec RabbitMQ, j’ai appris que même les clients expérimentés posent ces questions.

TL;DR > Consultez notre page produit RabbitMQ pour les cas d’utilisation, les fonctionnalités et pour contacter nos consultants experts.

Quel problème RabbitMQ résout-il ?

Avant de nous plonger dans ce qu’est RabbitMQ et comment l’utiliser, il vaut la peine d’en savoir plus sur le domaine du problème lui-même. La communication entre différents services (alias ordinateurs) est un problème vieux comme le monde.

D’une part, il y a les différents protocoles définissant le moyen de transport et les propriétés de la communication. Parmi ces protocoles, on peut citer SMTP, FTP, HTTP ou WebSockets (pour n’en citer que quelques-uns), qui sont tous basés sur TCP/UDP. Ils traitent du formatage, de la fiabilité et de la recherche du bon destinataire d’un message.

D’autre part, nous pouvons explorer la communication du point de vue du message. Il existe dans un système, puis il est transporté vers un autre, se transforme, c’est-à-dire qu’il a un cycle de vie. Lorsqu’il voyage d’un système à l’autre, nous devons savoir où se trouve le message et qui en est le propriétaire à un moment donné.

Les protocoles de communication mentionnés ci-dessus peuvent faire en sorte que la propriété (et l’emplacement « physique ») du message soit transférée d’un système à l’autre (bien que l’exécution de cette transaction puisse prendre un certain temps). Nous pouvons considérer le transfert comme une transaction entre les deux parties pendant qu’elles sont toutes deux présentes. La plupart du temps, cet échange actif est souhaitable, par exemple demander l’état d’un service et attendre une réponse rapide et précise. Un exemple tiré du monde physique serait d’appeler quelqu’un au téléphone :
1) on commence l’appel,
2) on attend que l’autre partie réponde,
3) on a une discussion agréable,
4) on raccroche le téléphone.

Mais il y a d’autres fois où nous n’avons pas besoin de la réponse, nous avons juste besoin que le récepteur s’approprie le message et fasse son travail. Dans ce cas, nous avons besoin d’un agent intermédiaire, un autre système pour prendre possession du message (temporairement) et s’assurer que le message arrive à destination. Pour pousser plus loin l’exemple du téléphone, l’autre partie n’est pas disponible pour le moment, nous laissons donc un message vocal. Le service de messagerie vocale notifiera le destinataire prévu.

Cette livraison asynchrone (différée) de messages est ce que RabbitMQ fournit. Évidemment, il peut faire plus qu’un simple répondeur, alors explorons certaines des options qu’il fournit ci-dessous

(Si vous souhaitez en savoir plus sur l’histoire de RabbitMQ, je vous recommande le premier chapitre de « RabbitMQ in Action » par Alvaro Videla et Jason Williams. Il révélera la réponse à la raison pour laquelle il est nommé d’après des lapins).

RabbitMQ est une solution gratuite, open-source et extensible de mise en file d’attente des messages. C’est un courtier de messages qui comprend AMQP (Advanced Message Queuing Protocol), mais qui peut également être utilisé avec d’autres solutions de messagerie populaires comme MQTT. Il est hautement disponible, tolérant aux pannes et évolutif. Il est implémenté en Erlang OTP, une technologie adaptée à la construction de systèmes stables, fiables, tolérants aux pannes et hautement évolutifs qui possèdent des capacités natives de gestion d’un très grand nombre d’opérations simultanées, comme c’est le cas avec RabbitMQ et d’autres systèmes comme WhatsApp, MongooseIM, pour n’en citer que quelques-uns.

À un très haut niveau, il s’agit d’une couche d’intergiciel qui permet à différents services de votre application de communiquer entre eux sans se soucier de la perte de messages tout en fournissant différentes exigences de qualité de service (QoS). Il permet également un routage de messages efficace et à grain fin permettant un découplage étendu des applications.

Cas d’utilisation

Pour montrer la polyvalence de RabbitMQ, nous allons utiliser trois études de cas qui démontrent comment RabbitMQ est bien adapté en tant qu’approche de service géré boîte noire, en tant que service qui s’intègre étroitement à l’application permettant une architecture de microservices qui fonctionne bien, ou en tant que passerelle vers d’autres projets hérités.

RabbitMQ comme bus de messages général

Lorsqu’un système monolithique est décomposé en sous-systèmes séparés, l’un des plus gros problèmes à résoudre est la technologie de communication à utiliser. Une solution comme Mulesoft, ou MassTransit peut « câbler » les services en déclarant des listeners et des senders HTTP. Ce type de solution traite RabbitMQ comme une boîte noire, mais est toujours capable de tirer parti des capacités de RabbitMQ. À titre d’exemple de communication directe, utilisons HTTP pour « connecter » les différents services. Bien que ce soit un choix solide et bien supporté, il présente quelques inconvénients :
1) La découverte des services n’est pas résolue. Une solution possible est d’utiliser le DNS. Au fur et à mesure que le système évolue et se développe, la complexité de la recherche et de l’équilibrage de cette charge augmente également. RabbitMQ peut atténuer la complexité accrue de la solution.
2) La communication est éphémère. Les messages sont susceptibles d’être abandonnés ou dupliqués sur la couche réseau. Si un service est temporairement indisponible, la livraison échoue.

RabbitMQ peut aider dans les deux cas en utilisant les files d’attente de messages comme moyen de transport. Les services peuvent publier et consommer des messages, ce qui permet de découpler la livraison des messages de bout en bout de la disponibilité du service de destination. Si un service consommateur est temporairement indisponible, contrairement à HTTP, le message est mis en mémoire tampon en toute sécurité et conservé dans RabbitMQ, et finalement livré lorsque le service revient en ligne.

La découvrabilité est également simplifiée. Tout ce que nous devons savoir, c’est où se trouve RabbitMQ et quel est le nom de la file d’attente. Bien qu’il semble que cela ne fasse que réinventer le problème, c’est évolutif. Le nom de la file d’attente agit comme l’adresse du service. La consommation des messages des files d’attente par les services individuels offre un moyen d’extensibilité, c’est-à-dire que chaque file d’attente peut servir plusieurs consommateurs et équilibrer la charge. Il n’est pas nécessaire de modifier la configuration des files d’attente déjà intégrée dans les services.

Cette configuration modérément statique des files d’attente pousse RabbitMQ vers une couche middleware où une conception solide peut garantir une qualité de service stable à long terme.

RabbitMQ comme couche de routage avancée pour les micro-services

À l’autre extrémité du spectre se trouve une architecture plus fluide qui s’adapte aux besoins en constante évolution de nombreux micro-services. Ce qui fait briller RabbitMQ dans cet environnement, ce sont les capacités de routage très puissantes qu’il fournit.

La logique de routage est mise en œuvre dans différents types d’échanges (dits) qui peuvent être créés dynamiquement par l’application en cas de besoin. Les services de destination créent les files d’attente qu’ils souhaitent consommer, puis les lient aux échanges en spécifiant un modèle pour les clés que les éditeurs peuvent utiliser lors de la publication du message. (Pensez à ces clés comme à des métadonnées que les échanges peuvent utiliser pour acheminer et livrer les messages à une ou plusieurs files d’attente.)

La logique d’acheminement est mise en œuvre dans différents types d’échanges (dits) qui peuvent être créés dynamiquement par l’application lorsque cela est nécessaire. Les services de destination créent les files d’attente qu’ils souhaitent consommer, puis les lient aux échanges en spécifiant un modèle pour les clés que les éditeurs peuvent utiliser lors de la publication du message. (Pensez à ces clés comme des métadonnées que les échanges peuvent utiliser pour acheminer et livrer les messages à une ou plusieurs files d’attente.)

RabbitMQ est livré avec quatre types d’échange utiles qui couvrent la plupart des cas d’utilisation de la messagerie:
1) Échange direct. Ceci délivrera le message entrant à toute file d’attente dont la clé de liaison correspond exactement à la clé de routage du message. Si vous liez les files d’attente avec le nom de la file d’attente comme clés de routage, alors vous pouvez penser à cela comme une livraison de message un à un. Il est simple de livrer le même message à plusieurs files d’attente en utilisant les clés de liaison pour plusieurs files d’attente.
2) Échange de sujets. Ceci délivrera le message entrant à toute file d’attente dont la clé de liaison joker correspond à la clé de routage du message publié. Les clés de liaison peuvent contenir des critères de correspondance joker pour une clé de routage composée. (par exemple, la clé de liaison logs.*.error correspondra aux clés de routage logs.accounting.error et logs.ui.error). Cela nous permet d’écrire des services simples où la logique est bien contenue, et le message arrivera aux bons services par la « magie » de RabbitMQ.
3) Échange de fanout. Certains messages doivent être livrés à toutes les files d’attente, c’est là qu’un échange fanout peut être utilisé au lieu d’écrire une logique multicast élaborée dans l’application. Avec un échange RabbitMQ fanout, chaque service lie la file d’attente appropriée à l’échange sans avoir besoin de spécifier une clé de liaison, et tout se passe automatiquement. Si une clé de liaison est spécifiée, l’échange fanout l’ignorera simplement et routera/diffusera toujours les messages vers toutes les files d’attente qui lui sont liées.
4) Échange d’en-têtes. Cet échange tire parti de la structure des messages AMQP et est capable d’effectuer un routage complexe basé sur les en-têtes (y compris les en-têtes personnalisés) du message AMQP. Les en-têtes sont des métadonnées attachées à chaque message envoyé via AMQP.

En plus des échanges, il existe d’autres fonctionnalités utiles dans RabbitMQ qui permettent la mise en œuvre d’une logique de messagerie très complexe. Parmi les fonctionnalités les plus importantes, citons :
1) Les plug-ins personnalisés. RabbitMQ est extensible en permettant à ses utilisateurs d’ajouter des plug-ins. Presque tous les aspects de RabbitMQ sont personnalisables, y compris la gestion, l’authentification et l’autorisation, les solutions de sauvegarde et le clustering.
2) Clustering. Lorsqu’un seul serveur RabbitMQ ne suffit pas, plusieurs brokers RabbitMQ peuvent être connectés pour travailler ensemble et faire évoluer le système. Cela peut permettre à RabbitMQ de traiter plus de messages ou d’augmenter la résilience aux erreurs.
3) Réglage de la qualité de service. La livraison de messages sensibles au temps peut être facilitée en attachant une valeur TTL (Time-to-Live) soit au message, soit à la file d’attente. Les messages hors délai peuvent être automatiquement livrés à une file d’attente Dead-letter. La combinaison de la logique de routage ordinaire et de ces fonctionnalités supplémentaires peut conduire à des logiques de routage très avancées. Une autre fonctionnalité utile est l’utilisation de files d’attente prioritaires où l’éditeur peut attribuer un niveau de priorité à chaque message. Il est également possible de limiter le nombre de messages non acquittés, ce qui permet de régler les performances des services consommateurs, dans ce cas, RabbitMQ applique un mécanisme de contre-pression.

RabbitMQ intégré dans les systèmes existants

Dans le cas d’utilisation précédent, j’ai mentionné la possibilité d’utiliser des plug-ins pour étendre les fonctionnalités de RabbitMQ. Cette puissante fonctionnalité permet à RabbitMQ d’agir comme une couche de médiation entre vos services RabbitMQ natifs (capables d’AMQP) et d’autres applications patrimoniales. Voici quelques exemples notables :
1) L’utilisation de RabbitMQ comme courtier MQTT en activant simplement un plug-in. Cela ouvre le paysage à de nombreuses technologies IoT.
2) Le plug-in JMS (Java Message Service) de RabbitMQ, qui permet à RabbitMQ de communiquer avec n’importe quelle solution de messagerie capable de JMS.
3) Si votre application utilise un protocole propriétaire pour communiquer, il est possible de développer un plugin personnalisé pour se connecter à n’importe quel service de ce type.

Conclusion

Comme le démontrent les exemples ci-dessus, il n’y a pratiquement rien avec lequel RabbitMQ ne peut pas communiquer. Mais comme pour toute chose dans la vie, cela a un prix. Bien que la configuration de RabbitMQ soit généralement simple, le simple nombre de fonctionnalités peut parfois être écrasant. Si vous rencontrez des problèmes lors de la conception, de l’implémentation ou du support de vos courtiers RabbitMQ, contactez notre équipe d’experts ici. Ou, si vous souhaitez démarrer votre carrière dans l’une des technologies les plus demandées, inscrivez-vous à notre cours de formation RabbitMQ de 3 jours.

Debugging RabbitMQ

Vous voulez un système intuitif qui facilite la surveillance et la maintenance de votre RabbitMQ ? Obtenez votre essai gratuit de 45 jours de WombatOAM maintenant.

Notre page de capacités RabbitMQ

.