Symfony Messenger
Nous allons voir comment utiliser le nouveau composant Messenger de Symfony
RabbitMQ est un message broker très complet et robuste, c'est pourquoi le comprendre et l'utiliser est assez simple. en revanche, le maîtriser l'est un peu moins... C'est pourquoi je vous propose cette série de deux articles. Vous pouvez retrouver la partie 2 en cliquant ici.
Bref, pour commencer, avant de manger du pâté de lapin il va falloir bouffer des carottes !
RabbitMQ a de nombreux points forts, ce qui en fait une solution utilisable sur tous types/tailles de projet.
En voici quelques-uns :
Erlang
ce qui en fait un logiciel très robusteOk, donc on va commencer par semer des carottes
Afin de pouvoir utiliser efficacement RabbitMQ il faut comprendre le fonctionnement du protocol AMQP
.
RabbitMQ est un message broker, son rôle est de transporter et router les messages depuis les publishers vers les consumers.
Le broker utilise les exchanges
et bindings
pour savoir si il doit délivrer, ou non, le message dans la queue.
Voici le fonctionnement global du broker
:
Le
publisher
va envoyer unmessage
dans unexchange
qui va, en fonction dubinding
, router lemessage
vers la ou lesqueues
. Ensuite unconsumer
va consommer les messages.
Nous allons donc détailler les différents éléments qui composent le broker
.
Le message est comme une requête HTTP, il contient des attributs
ainsi qu'un payload
.
Parmi les attributs
du protocol vous pouvez y ajouter des headers
depuis votre publisher.
Liste des properties du protocol content_type, content_encoding, priority, correlation_id, reply_to, expiration, message_id, timestamp, type, user_id, app_id, cluster_id
Les headers
seront disponibles dans attributes[headers]
.
L'attribut routing_key
, bien qu'optionnel, n'en est pas moins très utile dans le protocol.
Les bindings, ce sont les règles que les exchanges utilisent pour déterminer à quelle queue il faut délivrer le message.
Les différentes configurations peuvent utiliser la routing key
(direct/topic exchanges) ainsi que les headers
(header exchanges).
Dans le cas des exchanges
fanout, les queues
n'ont qu'à être bindées pour recevoir le message.
Nous allons détailler leurs utilisations.
Un exchange
est un routeur de message. Il existe différents types de routages définis par le type d'exchange
.
Vous publiez dans un exchange. Vous ne consommez pas un exchange !
Important à savoir : l'
exchange
amq.default
est l'exchange
par défaut de rabbit. Vous ne pouvez ni le supprimer ni vous binder dessus.
Cet exchange est auto bindé avec toutes les queues
avec une routing key
égale au nom de la queue.
L'exchange
fanout
est le plus simple. En effet il délivre le message à toutes les queues bindées.
L'exchange
direct
n'autorise que le binding utilisant strictement la routing key
.
Si la routing_key
du message est strictement égale à la routing_key
spécifiée dans le binding alors le message sera délivré à la queue.
binding.routing_key == message.routing_key
L'exchange
topic
délivre le message si routing_key
du message matche le pattern défini dans le binding.
Une routing key
est composé de plusieurs segments séparés par des .
. Il y a également 2 caractères utilisés dans le matching.
*
n'importe quelle valeur de segment
#
n'importe quelle valeur de segment une ou plusieurs fois
Par exemple pour la routing key
foo.bar.baz
foo.*.baz
matchfoo.*.*
matchfoo.#
matchfoo.#.baz
match*.*.baz
match#.baz
match#.bar.baz
match#
matchfoo.*
non trouvématch(binding.routing_key, message.routing_key)
L'exchange
headers
délivre le message si les headers
du binding matchent les headers du message.
L'option x-match
dans le binding permet de définir si un seul header ou tous doivent matcher.
Avec le x-match = any
le message sera délivré si un seul des headers du binding correspond à un header du message.
binding.headers[attrName1] == message.headers[attrName1]
OU
binding.headers[attrName2] == message.headers[attrName2]
Le message sera délivré si le header attrName1
(configuré au moment du binding) est égal au header attrName1
du message
OU
si le header attrName2
est égal au header attrName2
du message.
Avec le x-match = all
le message sera délivré si tous les headers du binding correspondent aux headers du message.
binding.headers[attrName1] == message.headers[attrName1]
ET
binding.headers[attrName2] == message.headers[attrName2]
Ici le message sera délivré seulement si les headers attrName1
ET attrName2
(du binding) sont égaux aux headers attrName1
et attrName2
du message.
Une queue est l'endroit où sont stockés les messages. Il existe des options de configuration afin de modifier leurs comportements.
Quelques options :
Vous publiez dans un exchange. Vous ne consommez pas un exchange ! (quand vous croyez publier dans une queue en réalité le message est publié dans l'
exchange
amq.default
avec larouting key
= queue name)
Le rôle du consumer
est d'exécuter un traitement après avoir récupéré un ou plusieurs messages
.
Pour ce faire il va réserver (prefetching) un ou plusieurs messages
depuis la queue
, avant d'exécuter un traitement.
Généralement si le traitement s'est correctement déroulé le consumer va acquitter le message avec succès (basic.ack).
En cas d'erreur le consumer
peut également acquitter négativement le message
(basic.nack).
Si le message
n'est pas acquitté, il restera à sa place dans la queue et sera re fetch un peu plus tard.
Vous voila maintenant fin prêts à récolter vos carottes !
Vous pouvez maintenant consulter la partie 2 (maîtrise), dans laquelle nous verrons comment attraper les lapins, et comment préparer le pâté. 😜
Auteur(s)
Anthony MOUTTE
_Développeur / Concepteur @ ElevenLabs_🚀 je suis très intéressé par la recherche et développement ainsi que les bonnes pratiques.
Vous souhaitez en savoir plus sur le sujet ?
Organisons un échange !
Notre équipe d'experts répond à toutes vos questions.
Nous contacterDécouvrez nos autres contenus dans le même thème
Nous allons voir comment utiliser le nouveau composant Messenger de Symfony
En tant que développeur nous avons tous déjà eu besoin de filtrer un jeu de donnés (array, collection, API etc...). Nous allons découvrir la librairie Xpression qui va nous permettre de filtrer différents contenus avec une syntaxe simplifiée.
Nous allons voir les changements et nouveautés que Symfony 4 nous apporte.