Le patron Transactional Outbox : publier des événements de manière fiable dans les microservices
Dans l’architecture moderne axée sur les événements (Event-Driven Architecture), les microservices émettent en permanence des événements métier (OrderCreated, PaymentProcessed) pour communiquer de manière découplée.
Cependant, publier un événement de façon 100% fiable pose un problème critique : Comment garantir que la mise à jour de la base de données et la publication de l’événement réussissent ou échouent ensemble ?
Si un microservice met à jour sa base de données locale puis tente d’envoyer un message via le réseau à un courtier de messages (Apache Kafka, RabbitMQ), une panne réseau ou un délai d’attente dépassé peut corrompre la cohérence des données.
C’est ici qu’intervient le Patron Transactional Outbox.
Ce guide explique le Problème de la double écriture (Dual-Write), le fonctionnement du motif Outbox, la comparaison entre Polling Publisher et Change Data Capture (Debezium CDC) ainsi que les meilleures pratiques.
Le problème de la double écriture (Dual-Write)
Lorsqu’un service effectue deux écritures séparées :
- Sauvegarder les données dans la base de données locale.
- Publier l’événement sur Kafka.
Si la base de données valide la transaction mais que l’envoi vers Kafka échoue, les services en aval ne seront jamais notifiés. Résultat : Incohérence des données.
Qu’est-ce que le patron Transactional Outbox ?
Ce motif s’appuie sur les transactions ACID locales de la base de données.
Au lieu d’envoyer le message directement sur le réseau, le service enregistre le contenu de l’événement dans une table dédiée appelée Outbox Table dans la même transaction locale que les données métier.
Les contraintes ACID garantissent que les deux opérations sont validées ensemble ou annulées ensemble.
Un composant séparé en arrière-plan (Message Relay) lit la table Outbox et transmet les messages au courtier de messages.
Stratégies de relais : Polling Publisher vs. CDC (Debezium)
1. Polling Publisher
Un processus lit régulièrement les messages non traités (SELECT * FROM outbox_events WHERE processed = FALSE), les envoie à Kafka puis met à jour leur statut.
- Avantages : Simple à mettre en œuvre.
- Inconvénients : Latence et surcharge de la base de données.
2. Change Data Capture (CDC avec Debezium)
Debezium lit directement les journaux de transactions (PostgreSQL WAL) et transmet immédiatement les modifications à Kafka.
- Avantages : Latence quasi nulle et performances maximales.
- Inconvénients : Nécessite l’infrastructure Kafka Connect et Debezium.
Conclusion
Le Patron Transactional Outbox est indispensable pour garantir la cohérence éventuelle dans les architectures microservices distribuées.