Publications

Building a Resilient Site-Aware Synchronization

How to leverage RabbitMQ Cluster along with Outbox Pattern

Résumé

Le décor est un de ceux dans lesquels je travaille: plusieurs sites on-premise, chacun avec sa base locale, certaines sous PostgreSQL et d’autres sous Oracle, avec des contraintes réseau qui excluaient toute solution cloud native. Chaque site devait continuer à fonctionner seul, même pendant une coupure de plusieurs jours, et les données devaient malgré tout converger entre les sites une fois la liaison revenue.

Les outils de réplication classiques, GoldenGate ou SymmetricDS, ont été envisagés puis écartés: ils apportent leur propre complexité opérationnelle, et les conflits de synchronisation restent à traiter de toute façon. J’ai préféré une conception événementielle. Chaque écriture part dans une table outbox locale, dans la même transaction que la donnée métier; un dispatcher publie ces événements vers un cluster RabbitMQ à trois nœuds avec des quorum queues; un échange fanout livre chaque événement à chaque site, y compris celui qui l’a émis, ce qui lui permet de savoir que son événement a bien circulé.

Deux propriétés font tenir l’ensemble. Chaque événement porte un identifiant unique, donc un consommateur qui le voit deux fois ne l’applique qu’une fois. Et un site joue la source de référence: il archive tous les événements, ce qui donne une piste d’audit, une fenêtre de rétention et la possibilité de rejouer. Les conflits partent dans une file de lettres mortes pour qu’un humain les examine. Un événement de confirmation, optionnel, renvoyé par chaque site consommateur, facilite encore la détection des rejeux et le débogage.

L’article se termine sur un choix souvent fait trop vite: clustering, fédération ou shovel pour relier des brokers RabbitMQ, chacun avec des garanties différentes sur l’ordre et la livraison. La réponse dépend du besoin métier, pas de l’habitude. Le dépôt qui accompagne l’article lance le cluster avec Docker Compose et permet d’éteindre un broker pour voir le reste continuer.

Idées clés

  • Des sites qui doivent survivre à des jours sans réseau demandent d’abord l’autonomie et ensuite la cohérence; la réplication classique ajoute de la complexité sans supprimer les conflits.
  • Une outbox écrite dans la même transaction que la donnée métier, puis publiée vers RabbitMQ, pour que rien ne se perde tant que le broker est injoignable.
  • Un échange fanout livre chaque événement à chaque site, émetteur compris, ce qui lui permet de savoir que son événement a circulé.
  • Un identifiant d’événement unique rend les consommateurs idempotents; un site source de référence archive tout pour l’audit et le rejeu.
  • Clustering, fédération ou shovel entre brokers est une décision métier, pas une habitude.

Pourquoi j’ai écrit cet article

Dans notre cas, nous gérons plusieurs sites on-premise, chacun avec sa base locale, certaines sous PostgreSQL, d’autres sous Oracle. Une solution cloud native n’était pas viable sous des contraintes réseau strictes, et chaque site devait fonctionner de façon indépendante, sans dépendre d’une connectivité en temps réel.

Dépôts associés