16 - Orchestration vs chorégraphie: le pattern Saga

Les processus métiers distribués exigent une cohérence sans transactions globales. Le pattern Saga permet d’enchaîner des transactions locales tout en gérant les compensations en cas d’échec. En banque, les sagas sont la colonne vertébrale des flux complexes: virements internationaux, ouverture de compte, paiements cartes, ou parcours KYC.

Ce chapitre détaille l’orchestration et la chorégraphie, leurs avantages, leurs risques et les bonnes pratiques pour des sagas robustes.

C’est quoi une saga ?

Une saga est une suite d’étapes, chacune exécutée par un service différent. Chaque étape est une transaction locale. Si une étape échoue, des actions de compensation annulent les étapes précédentes.

Exemple bancaire: un virement international peut nécessiter: - validation du solde, - check AML, - conversion FX, - écriture ledger, - notification client.

Si l’étape FX échoue, on doit annuler la réservation de fonds et informer le client. C’est exactement le rôle d’une saga.

Orchestration

Un orchestrateur central pilote le flux via des commandes et attend des réponses.

Avantages

  • Vision globale du workflow.
  • Débogage plus simple.
  • Gestion centralisée des timeouts et des compensations.

Inconvénients

  • Point de couplage fort.
  • Risque d’effet “monolithe” si l’orchestrateur devient trop complexe.
  • Nécessite une haute disponibilité.

Chorégraphie

Chaque service réagit aux events et publie le suivant. Il n’y a pas de coordinateur central.

Avantages

  • Découplage fort.
  • Scalabilité naturelle.
  • Faible dépendance à un composant central.

Inconvénients

  • Workflow implicite difficile à tracer.
  • Debug complexe (il faut reconstituer le flux depuis les logs).
  • Risque de “passive-aggressive commands”.

Orchestration vs chorégraphie: comparaison

Critère Orchestration Chorégraphie
Couplage Centralisé Distribué
Traçabilité Forte Faible sans observabilité
Complexité Concentrée Diffuse
Résilience Dépend de l’orchestrateur Dépend du réseau d’events
Évolutivité Moyenne Élevée

Dans une banque, l’orchestration est souvent choisie pour les flux critiques qui exigent un contrôle strict (paiements, compliance). La chorégraphie est adaptée aux flux plus souples (notifications, analytics).

Commands vs events dans une saga

  • Command: intention d’agir, adressée à un service.
  • Event: fait accompli, publié après validation.

Une saga robuste alterne commands et events. Exemple: 1) Orchestrateur envoie ReserveFunds. 2) Service Comptes publie FundsReserved. 3) Orchestrateur envoie ExecuteFX. 4) Service FX publie FxExecuted.

Cette séparation clarifie qui décide et qui atteste.

Modéliser la saga comme une machine d’état

Une saga est plus facile à maîtriser lorsqu’elle est explicitement modélisée comme une machine d’état. Chaque étape correspond à un état, et chaque event valide une transition. Exemple bancaire: - TRANSFER_INITIATED -> FUNDS_RESERVED -> AML_CLEARED -> FX_EXECUTED - état terminal: SETTLED ou REJECTED

Cette modélisation clarifie les transitions autorisées et évite les sauts non contrôlés. Elle facilite aussi la supervision: un orchestrateur peut détecter une saga bloquée, appliquer un timeout, et déclencher une compensation automatique avant que l’état ne se dégrade.

Pour les flux critiques, l’état de saga est persisté avec un saga log contenant: saga_id, état courant, timestamps, et historique des étapes.

Compensation, retry et reversal

Une compensation n’est pas un rollback technique. Elle doit respecter les contraintes métier. Dans une banque: - Retry: réessayer une étape qui a échoué pour cause transitoire. - Compensation: annuler un effet métier (libérer les fonds). - Reversal: correction comptable explicite, enregistrée dans le ledger.

Ces mécanismes sont complémentaires. Par exemple, on peut retry un appel FX pendant 30 secondes, puis compenser en libérant les fonds si l’échec persiste. La reversal est utilisée lorsque l’effet est déjà visible comptablement.

Timeouts et deadlines

Une saga doit définir des délais explicites. Sans timeouts, elle peut rester bloquée et laisser le système dans un état intermédiaire. Dans un flux bancaire critique, un timeout déclenche une compensation automatique et une alerte.

Les deadlines doivent être cohérentes avec les SLA métiers: un virement instantané n’a pas le même budget de temps qu’un transfert international.

Idempotence et déduplication

Une saga traverse plusieurs services et peut rejouer certains messages. Chaque étape doit être idempotente. Un service ne doit pas exécuter deux fois la même réservation de fonds.

Les clés d’idempotence sont souvent basées sur saga_id ou command_id. Pour les flux comptables, la déduplication est non négociable.

Stockage de l’état de saga

Orchestration

L’orchestrateur maintient un saga log: état courant, étapes terminées, compensations. Ce log est indispensable pour la reprise après incident.

Chorégraphie

Chaque service conserve un état local et réagit aux events. Le flux global est reconstruit via correlation_id.

En banque, l’orchestration est plus facile à auditer car l’état central est explicit.

Process manager et règles de décision

Dans une saga orchestrée, l’orchestrateur joue souvent le rôle de process manager: il connaît l’état global et prend les décisions de transition. Dans une banque, ces décisions sont encadrées par des règles strictes (AML, limites de montant, statut KYC). L’orchestrateur ne doit pas \“deviner\” la logique interne des services; il se base sur les events publiés.

Une bonne pratique est de garder l’orchestrateur mince: il pilote, mais ne réimplémente pas les règles métier des services. Cela limite le couplage et évite que l’orchestrateur devienne un monolithe distribué.

Sécurité et conformité

Les sagas critiques manipulent des données sensibles. Elles doivent respecter les exigences de sécurité: - propagation des identités (qui a initié la saga), - journalisation des décisions, - séparation des topics sensibles.

En banque, l’orchestrateur doit produire un log d’audit lisible: pourquoi une saga a été rejetée, quelles compensations ont été appliquées, et à quel moment. Cette traçabilité est indispensable pour les audits internes et externes.

Mise à l’échelle et partitioning

Une saga peut devenir un goulot d’étranglement si l’orchestrateur est unique. La mise à l’échelle passe par le partitioning: une saga est routée via une clé stable (saga_id, transfer_id). Chaque instance de l’orchestrateur gère un sous-ensemble de sagas. Cela préserve l’ordre des étapes et augmente la capacité globale.

En chorégraphie, la mise à l’échelle est plus naturelle, mais elle exige des consumers strictement idempotents et une observabilité solide.

Sagas et pattern Outbox

Les commands et events d’une saga doivent être publiés de manière cohérente. Le pattern Outbox est recommandé: l’orchestrateur écrit sa décision dans sa base et publie la command via une outbox. Sans cela, un crash peut laisser la saga dans un état incohérent (commande envoyée mais état non persisté).

Dans les architectures bancaires, ce pattern est systématique pour les orchestrateurs, car il garantit la traçabilité et la reproductibilité.

Observabilité avancée des sagas

Les sagas critiques doivent être instrumentées avec des métriques dédiées: - nombre de sagas actives, - distribution des durées par étape, - taux de compensation, - taux d’échec par service.

Cette observabilité permet d’identifier les goulots d’étranglement, par exemple un service AML plus lent après une mise à jour de règles.

Gestion des exceptions métiers

Toutes les erreurs ne se résolvent pas par une compensation automatique. Dans les banques, certaines situations exigent une revue manuelle: suspicion de fraude, incohérence de données, litige client. Une saga robuste doit prévoir un chemin de sortie “manuel” qui met la transaction en attente et déclenche une procédure humaine.

Ce chemin doit être explicite dans le modèle de saga, avec un état dédié (REVIEW_REQUIRED) et des règles de reprise. Sans cela, les erreurs critiques restent invisibles ou sont traitées de manière automatique alors qu’elles devraient être examinées.

Versioning des contrats de saga

Une saga combine plusieurs commands et events. Si ces contrats évoluent, la saga doit pouvoir gérer plusieurs versions en parallèle. Exemple: une nouvelle version de ReserveFunds peut ajouter un champ de risque. L’orchestrateur doit être capable de traiter l’ancienne et la nouvelle version pendant une période de migration.

Cette compatibilité est essentielle pour éviter les interruptions de flux. En banque, les migrations doivent être progressives et alignées avec les fenêtres de changement validées par la conformité.

Tests de scénarios et simulation

Tester une saga ne se limite pas aux tests unitaires. Il faut simuler des scénarios d’échec: timeout, duplication, ordre inversé. Les banques utilisent souvent des environnements de simulation pour rejouer des flux complets et valider que les compensations fonctionnent.

Les tests end-to-end révèlent les dépendances cachées entre services et la qualité des mécanismes d’idempotence.

Réconciliation et reporting

Une saga n’est pas seulement un flux technique, elle produit des effets métier qui doivent être réconciliés. En banque, il est courant de comparer l’état final d’une saga avec les écritures comptables et les projections de reporting. Un écart doit déclencher une investigation. Cette discipline est essentielle pour garantir que les compensations ont bien été appliquées et que l’état final est conforme aux règles métier. Les systèmes matures enregistrent des événements de suivi (SagaCompleted, SagaCompensated) consommés par un service de contrôle interne. Ce service produit des indicateurs: taux de compensation, temps moyen de traitement, proportion de sagas passées en revue manuelle. Ces métriques permettent d’ajuster les règles et de détecter des dérives opérationnelles.

Bonnes pratiques de base

  • Versionner les commands et events.
  • Isoler les topics de saga.
    • prod.payments.transfer.cmd.reserve.v1
    • prod.payments.transfer.evt.reserved.v1
    • prod.payments.transfer.saga.dlq.v1
  • Documenter les compensations.
  • Tester les timeouts et les scénarios d’échec.

Exemple bancaire: saga de virement international (orchestration)

1) Orchestrateur reçoit InitiateTransfer. 2) Command ReserveFunds -> event FundsReserved. 3) Command CheckAML -> event AmlCleared. 4) Command ExecuteFX -> event FxExecuted. 5) Command PostLedger -> event TransferSettled. 6) Command NotifyClient -> event NotificationSent.

Si CheckAML échoue, l’orchestrateur déclenche ReleaseFunds et publie TransferRejected.

Chorégraphie: même scénario

1) TransferInitiated publié. 2) Service Comptes réserve et publie FundsReserved. 3) Service AML publie AmlCleared. 4) Service FX publie FxExecuted. 5) Ledger publie TransferSettled. 6) Notifications publie NotificationSent.

La logique est plus distribuée, mais le workflow est moins explicite.

Un point clé est la gestion du temps métier. Une saga peut durer quelques secondes (paiement instantané) ou plusieurs heures (virement international avec contrôles manuels). Cette durée influence le design des timeouts, la stratégie de compensation et la charge opérationnelle.

Pièges à éviter

  • Utiliser un event comme commande implicite.
  • Oublier les timeouts.
  • Ne pas stocker l’état de saga.
  • Laisser un orchestrateur devenir un monolithe.
  • Ne pas instrumenter les sagas critiques.

Conclusion

Le pattern Saga est indispensable pour coordonner des transactions distribuées. L’orchestration offre contrôle et lisibilité; la chorégraphie offre découplage et scalabilité. En banque, le choix dépend du niveau de risque et de la criticité métier. La discipline sur l’idempotence, la compensation et l’audit est la condition d’une saga robuste. Elle assure une cohérence métier durable tout en maintenant la souplesse nécessaire à l’évolution des services bancaires distribués. C’est un pilier des architectures event-driven bancaires modernes et sûres à l’échelle des organisations complexes.