Message brokers : faire communiquer des services sans les coller ensemble
Comprendre queues, producteurs, consommateurs, acknowledgements et pub/sub avant RabbitMQ, Kafka et les architectures événementielles.
Où en êtes-vous avec cette notion ?
Une indication personnelle, enregistrée uniquement dans ce navigateur.
Le format café
L’essentiel à comprendre, le temps d’un café.
Envie de creuser ? Un cours plus complet vous attend juste après, à déplier sans quitter cette page.
Le concept
Un message broker reçoit des messages d’une application et les transmet à d’autres.
Producteur → Broker → Consommateur
Sans broker, un service Commande peut appeler directement Email, Stock et Analytics. Une panne secondaire peut alors ralentir le parcours principal. Avec un broker, Commande publie OrderCreated et les autres services réagissent indépendamment.
Queue
Une queue conserve des messages en attente. Plusieurs workers peuvent se partager le travail :
[M1][M2][M3] → Worker A
└→ Worker B
Acknowledgement
Après traitement, le consumer peut confirmer avec un ack. S’il plante avant, le message peut être livré à nouveau. Cela explique pourquoi l’idempotence est si importante.
Queue et pub/sub
Une work queue distribue du travail. Le publish/subscribe permet à plusieurs applications de réagir au même événement.
Commande et événement
GenerateInvoice demande une action. InvoiceCreated annonce un fait déjà produit.
RabbitMQ et Kafka
RabbitMQ est très naturel pour queues, workers et routage. Kafka est une plateforme d’event streaming : les événements sont stockés durablement dans des topics et peuvent être relus.
À retenir
Le broker découple, tamponne et route. Il est utile pour les traitements différés, les pics de charge et les réactions multiples à un événement. Il apporte aussi de nouveaux sujets à maîtriser : doublons, retries, ordre, DLQ et observabilité.
Et si on allait plus loin ?
Le café vous a donné les repères. Prenez maintenant le temps de comprendre les mécanismes et de pratiquer, si vous le souhaitez.
Aller plus loinMessage brokers en profondeur : architecture, fiabilité et systèmes événementielsDévelopper le coursReplier le cours
Objectif
Comprendre pourquoi les message brokers existent et savoir raisonner sur queues, pub/sub, fiabilité, doublons, retries, DLQ, ordre, montée en charge et choix RabbitMQ/Kafka.
1. Pourquoi un broker ?
Une commande e-commerce peut déclencher stock, email, facturation, impression et analytics. Si l’API appelle tout directement, chaque dépendance peut ralentir ou casser le parcours.
Client → Commande → Stock
├→ Email
└→ Analytics
Avec un broker, Commande publie un message et les traitements secondaires avancent indépendamment.
Client → Commande → BDD
└→ Broker → Stock
├→ Email
└→ Analytics
2. Synchrone vs asynchrone
En synchrone, A appelle B et attend. En asynchrone, A remet un message puis peut continuer. Asynchrone ne veut pas dire automatiquement plus rapide : on gagne surtout en découplage et en absorption des variations de charge, au prix d’une complexité distribuée.
3. Vocabulaire
Producer/publisher publie. Consumer/subscriber traite. Le broker est l’intermédiaire. Une queue conserve du travail en attente. Un topic est un canal logique. Le payload contient les données métier. Un ack confirme réception ou traitement selon le protocole.
4. Message, commande, événement
Une commande exprime une intention : GenerateInvoice. Un événement décrit un fait : OrderCreated. Un producteur d’événement peut ignorer quels consommateurs futurs seront intéressés.
5. Enveloppe du message
{
"eventId": "evt_123",
"type": "order.created",
"version": 1,
"occurredAt": "2026-09-03T18:00:00Z",
"correlationId": "req_456",
"payload": { "orderId": "cmd_789", "total": 32.5 }
}
L’ID aide à dédupliquer, le type formalise le contrat, la version aide son évolution et le correlation ID le traçage distribué. N’envoyez pas de données sensibles inutiles.
6. Work queues
Producer → [M1 M2 M3 M4] → Worker A
├→ Worker B
└→ Worker C
Plusieurs workers se partagent des jobs. C’est adapté aux PDF, emails, miniatures ou traitements lourds. Ajouter des workers aide jusqu’à ce qu’une autre dépendance devienne le goulot.
7. Publish/subscribe
┌→ Stock
OrderCreated → Bus ─┼→ Email
└→ Analytics
Chaque consommateur réagit indépendamment. Ajouter Analytics ne devrait idéalement pas modifier Commande.
8. RabbitMQ
Dans le modèle AMQP 0-9-1 courant de RabbitMQ, un publisher publie vers un exchange. Des bindings routent vers des queues, puis les consumers les traitent.
Publisher → Exchange ─→ Queue email → Consumer
└─→ Queue stock → Consumer
Les tutoriels RabbitMQ présentent work queues, publish/subscribe, routing et topics. RabbitMQ est très naturel pour distribution de jobs et routage de messages.
9. Kafka
Kafka ressemble davantage à un journal distribué. Un topic possède des partitions :
orders P0: [0][1][2][3]
P1: [0][1][2]
Les événements sont conservés selon une rétention et le consumer suit son offset. Ils peuvent être relus : c’est central pour streaming, nouveaux consumers et reconstruction de traitements.
10. RabbitMQ vs Kafka
| Besoin dominant | Modèle souvent naturel |
|---|---|
| Jobs / workers | RabbitMQ |
| Routage riche | RabbitMQ |
| Événements durables et rejouables | Kafka |
| Gros flux événementiels | Kafka |
| Journal + offsets | Kafka |
Leurs fonctionnalités se recouvrent : choisissez selon vos garanties et opérations réelles.
11. Acknowledgements
Le consumer reçoit M42, écrit en base puis plante avant son ack. Le broker peut relivrer M42. La redelivery est donc un scénario normal à concevoir, pas seulement une anomalie.
12. Garanties de livraison
At-most-once : perte possible, pas de redelivery volontaire. At-least-once : on privilégie l’absence de perte, avec doublons possibles. Exactly-once : toujours préciser la frontière. Une transaction interne à une plateforme ne peut pas annuler un email ou paiement externe déjà effectué.
13. Idempotence
BEGIN
si event_id déjà traité → ignorer
sinon
appliquer effet métier
mémoriser event_id
COMMIT
Quand possible, effet métier et mémorisation sont atomiques. Pour un paiement, combinez cela aux mécanismes d’idempotence du prestataire.
14. Retry, backoff, jitter
Une panne temporaire mérite parfois un retry : 1 s, 2 s, 4 s, 8 s… C’est l’exponential backoff. Un jitter évite que tous les workers retentent simultanément. Les retries doivent être bornés ; un payload invalide ne guérira pas au 10 000e essai.
15. DLQ et poison messages
Après N échecs, un message peut être isolé dans une dead-letter queue. Un message échouant systématiquement est un poison message. Une DLQ doit avoir alertes, métriques, inspection et procédure de replay : ce n’est pas une poubelle.
16. Ordre
Un ordre global limite le parallélisme. Souvent, seul l’ordre par entité compte. Les événements de commande 42 restent ordonnés, tandis que commandes 42 et 99 avancent en parallèle. Dans Kafka, l’ordre est notamment lié à la partition.
17. Backpressure
Si les producers créent 20 000 messages/s et les consumers en traitent 5 000 :
20k/s → [ backlog ↑↑↑ ] → 5k/s
Surveillez profondeur de queue ou lag, âge du plus vieux message, débit, erreurs et durée de traitement. Le broker tamponne mais n’invente pas de capacité.
18. Concurrence et prefetch
Trop de messages en vol peuvent déséquilibrer les workers. Selon la technologie, prefetch ou contrôle de flux limitent les messages non acquittés. Trop de workers peuvent saturer PostgreSQL ou une API externe : mesurez.
19. Dual write
1. INSERT commande ✓
2. publish OrderCreated ✗
La commande existe sans événement. Publier d’abord crée le problème inverse. Deux systèmes indépendants ne constituent pas spontanément une transaction atomique.
20. Transactional Outbox
Écrivez mutation et événement dans la même transaction locale :
BEGIN
INSERT orders ...
INSERT outbox_events ...
COMMIT
Un publisher lit ensuite l’outbox et publie au broker. Il peut republier après panne, donc les consumers restent idempotents.
21. Inbox / déduplication
Côté réception, une table processed_messages peut conserver les IDs traités. L’outbox fiabilise la publication ; inbox/déduplication protège la consommation.
22. Évolution des schémas
Producer et consumer ne sont pas forcément déployés ensemble. Le message est un contrat distribué. Favorisez ajouts compatibles, champs optionnels, tolérance aux champs inconnus et versionnement des ruptures. À grande échelle, JSON Schema, Avro ou Protobuf et un schema registry peuvent aider.
23. Événement minimal ou riche
OrderCreated { orderId } force parfois le consumer à rappeler le service source. Un événement plus riche le rend autonome mais augmente taille et duplication. Transportez ce que le contrat nécessite, pas toute votre base.
24. Event-driven ≠ event sourcing
Event-driven signifie communiquer/réagir par événements. Event sourcing signifie conserver les événements métier comme source de vérité permettant de reconstruire l’état. Utiliser Kafka ne signifie pas automatiquement faire de l’event sourcing.
25. Observabilité
Une API peut répondre 200 alors qu’un consumer échoue cinq minutes plus tard. Mesurez publications, consommations, backlog/lag, âge des messages, retries, DLQ et durée de traitement. Propagez un correlation ID ou contexte de trace.
26. Sécurité
Utilisez chiffrement réseau, authentification, autorisations minimales, rotation des secrets, séparation des environnements et audit. Un broker « interne » n’est pas une raison pour transporter des secrets en clair dans les payloads.
27. Panne du broker
Le producer doit avoir une stratégie : échouer proprement, retenter, utiliser une outbox ou dégrader une fonctionnalité secondaire. Réplication et haute disponibilité réduisent le risque mais ne remplacent pas une stratégie de récupération.
28. Microservices
Un broker n’est pas réservé aux microservices : un monolithe peut utiliser une queue de jobs. Et des microservices peuvent communiquer en HTTP. N’introduisez pas Kafka uniquement parce que l’architecture comporte plusieurs services.
29. Quand utiliser un broker ?
Bon candidat lorsque le traitement peut être différé, plusieurs systèmes réagissent au même fait, la charge arrive par pics, les disponibilités doivent être découplées ou un flux durable/rejouable est nécessaire.
Restez synchrone quand le demandeur a besoin immédiatement du résultat et que la simplicité vaut davantage que le découplage.
30. Cas concret : click & collect
POST /orders
├→ transaction BDD
│ ├→ order
│ └→ outbox: OrderCreated
└→ 201
Outbox publisher → Broker
├→ Kitchen
├→ Email
└→ Analytics
Email peut tomber sans empêcher la commande. Après reprise, son consumer rattrape les messages. Le consumer cuisine mérite une surveillance plus stricte car il appartient au parcours opérationnel critique.
31. Checklist
Avant de créer une queue ou un topic : est-ce une commande ou un événement ? Qui en est propriétaire ? Que se passe-t-il si le message arrive deux fois ? Quelle garantie de livraison ? Quel ordre ? Quels retries ? Quelle DLQ ? Comment versionner ? Comment observer ? Que faire si le broker tombe ? Comment rejouer sans doubles effets ?
32. Pièges fréquents
- Croire qu’un broker supprime les pannes.
- Croire que « exactly once » règle tous les effets externes.
- Ack avant de sécuriser l’effet métier.
- Retry infini sans backoff.
- DLQ sans surveillance.
- Consumer non idempotent.
- Ordre global inutile.
- Dual write ignoré.
- Schéma cassé sans migration des consumers.
- Choisir Kafka/RabbitMQ par mode plutôt que par besoin.
33. Exercice
Après un paiement, une application doit générer un PDF (15 s), envoyer un email et alimenter Analytics, parfois indisponible. Concevez un flux rapide pour l’API et tolérant aux redeliveries.
Correction
Après validation transactionnelle du paiement, écrivez PaymentConfirmed dans une outbox. Un publisher l’envoie au broker. Facture génère le PDF de manière idempotente puis publie InvoiceGenerated; Email le consomme avec déduplication. Analytics consomme indépendamment et rattrape son retard. Erreurs transitoires : backoff ; erreurs permanentes : DLQ + alerte.
Sources
- RabbitMQ — Tutorials
- RabbitMQ — AMQP 0-9-1 Model Explained
- Apache Kafka — Introduction
- OASIS — AMQP 1.0
Mémo final
Un broker est un outil de découplage temporel et spatial. Il tamponne, route et distribue, mais introduit un système distribué. La vraie compétence consiste donc à concevoir pannes, doublons, délais, contrats et reprises avant qu’ils arrivent.
Vous pouvez aussi vous arrêter ici. L’approfondissement est facultatif.
Les repères Cours Café
Pour aller à la source
Documentation de référence. Vérification éditoriale encore à effectuer.
Gardez une trace de cette idée.
Favoris, notes et progression seront disponibles après connexion du stockage distant.