Implémentez un Orchestrateur de Saga centralisé en utilisant Temporal ou Netflix Conductor qui maintient l'état de flux de travail durable dans PostgreSQL avec une communication gRPC vers les services de domaine. Le modèle nécessite des clés d'idempotence stockées dans un Redis Cluster avec des fenêtres TTL correspondant aux contraintes commerciales, tandis qu'Apache Kafka sert de colonne vertébrale événementielle pour les pistes d'audit et les déclencheurs de compensation. Chaque étape de la saga doit inclure des transactions de compensation qui exécutent des opérations inverses en utilisant le modèle de la Machine d'État de Saga, avec des états explicites (EN ATTENTE, RÉUSSI, COMPENSATION, COMPENSÉ) suivis dans etcd ou ZooKeeper pour la coordination de cluster.
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ API Gateway │────▶│ Temporal │────▶│ Inventory │
└─────────────────┘ │ Orchestrator│ │ Service │
└──────────────┘ └─────────────────┘
│ │
▼ ▼
┌──────────────┐ ┌─────────────────┐
│ PostgreSQL │ │ PostgreSQL │
│ State Store │ │ (Logique de │
└──────────────┘ │ Compensation) │
└─────────────────┘
Une plateforme de réservation d'hôtels mondiale a lutté contre des défaillances en cascade lors de la coordination des réservations de chambres, du traitement des paiements et des mises à jour de points de fidélité à travers trois clusters Kubernetes distincts dans différentes régions. Leur mise en œuvre hérité utilisait Two-Phase Commit (2PC) sur des API REST, provoquant d'énormes blocages pendant les périodes de pointe lorsque la passerelle de paiement connaissait des pics de latence dépassant 10 secondes.
L'équipe a évalué la Saga basées sur la chorégraphie en utilisant Amazon EventBridge, où chaque service publiait des événements de domaine sur un bus partagé. Cette approche a éliminé le point de défaillance unique et réduit les coûts d'infrastructure de 40 %. Cependant, elle a introduit de graves défis d'observabilité, car déterminer si une réservation complexe de plusieurs chambres avait réussi nécessitait de consulter les journaux à travers dix-sept microservices. Les dépendances implicites rendaient impossible l'application de politiques de délai d'attente cohérentes, et le débogage des problèmes de production devenait un exercice d'analyse forensique s'étendant sur plusieurs tableaux de bord AWS CloudWatch.
Ils ont prototypé une Saga Orchestrée en utilisant un coordinateur Node.js personnalisé déployé sur AWS ECS. Cela a centralisé la logique métier et simplifié le suivi à travers un tableau de bord unifié Grafana. Malheureusement, la mise en œuvre initiale stockait l'état du flux de travail uniquement en mémoire, entraînant une perte de données catastrophique lorsque le coordinateur redémarrait pendant les déploiements. Trente transactions sont entrées dans des états inconnus, nécessitant une réconciliation manuelle de la base de données qui a duré trois jours et a entraîné une perte de revenus significative due à des clients facturés deux fois.
La solution choisie a déployé Temporal comme moteur de flux de travail avec une persistance Cassandra, garantissant la durabilité d'état à travers les redémarrages de pod et les pannes d'AZ. L'architecture utilisait des schémas Protobuf pour une communication sécurisée par type entre l'orchestrateur et les services de domaine, avec Redis Sentinel gérant les clés d'idempotence. Lorsque le service de paiement a subi une panne régionale dans us-east-1, la saga a automatiquement déclenché des flux de travail de compensation qui ont levé les réservations de chambres en moins de 200ms et révoqué les points de fidélité de manière atomique.
Le système traite désormais 50 000 réservations complexes par jour avec 99,99 % de garanties de cohérence et zéro intervention manuelle pendant les partitions réseau. Le temps moyen de détection (MTTD) des pannes est passé de 45 minutes à 8 secondes, tandis que la latence de compensation reste inférieure à 500ms au p99.
Comment gérez-vous un échec partiel de compensation lorsque qu'une transaction de compensation échoue elle-même, laissant potentiellement le système dans un état incohérent ?
Implémentez un Journal d'Audit de Compensation en utilisant Event Sourcing où chaque tentative de compensation est enregistrée comme un événement immuable dans Apache Kafka avec une conservation infinie. Le système doit distinguer entre les défaillances d'infrastructure transitoires nécessitant une nouvelle tentative automatique avec un retour exponentiel et les violations de logique métier requérant une intervention humaine. Pour les problèmes transitoires, utilisez des Dead Letter Queues (DLQ) dans RabbitMQ ou Amazon SQS qui reprocessent les compensations après la récupération du service avec du jitter pour éviter les ruées de tonnerre. Pour les violations de règles d'entreprise, telles que tenter de rembourser une transaction déjà soldée, la saga entre dans un état 'COMPENSATION_FAILED' qui déclenche des alertes PagerDuty tout en appliquant le modèle CQRS pour geler la racine d'agrégation via le modèle de commande. Conçez toujours des compensations pour être idempotentes en utilisant des contraintes uniques de base de données ou des opérations SETNX de Redis, garantissant que les nouvelles tentatives ne créent pas d'effets secondaires.
Quelle est la différence architecturale fondamentale entre chorégraphie et orchestration concernant le couplage temporel et la capacité à répondre à des requêtes 'quel est l'état actuel de la transaction' ?
La Chorégraphie suit le Manifeste Réactif, créant un découplage temporel où les services réagissent aux événements sans connaissance des participants en amont ou en aval, mais en sacrifiant la capacité de requêter l'état de la saga sans construire une Traçabilité Distribuée complexe avec Jaeger ou AWS X-Ray. L'état devient émergent des journaux d'événements, nécessitant des projections de modèles de lecture CQRS pour répondre à des questions 'la réservation est-elle complète ?'. L'Orchestration introduit un couplage temporel explicite entre le coordinateur et les travailleurs, car l'orchestrateur doit être disponible pour déclencher les prochaines étapes, mais fournit une source unique de vérité dans son magasin d'état (PostgreSQL/CockroachDB). Cela permet des requêtes d'état immédiates, mais crée une dépendance réseau. L'aperçu critique est que la chorégraphie nécessite la mise en œuvre de machines d'état dans chaque consommateur, tandis que l'orchestration centralise cette complexité ; pour les systèmes nécessitant une forte auditabilité et conformité (PCI-DSS), l'orchestration est préférée malgré le coût du couplage.
Comment prévenez-vous l'exécution de saga en double lors de l'utilisation de sémantiques de livraison au moins une fois dans des courtiers de messages pendant le rebalancement du consommateur Kafka ou les redémarrages des pods Kubernetes ?
Implémentez des modèles de Consommateur Idempotent en utilisant Redis ou Memcached pour stocker les ID de messages traités avec des fenêtres de dé-duplication correspondant à votre Objectif de Point de Récupération (RPO), généralement 24-48 heures pour les systèmes financiers. Lorsque l'orchestrateur de saga reçoit une commande, générez une clé d'idempotence déterministe en hachant l'ID de corrélation avec une clé commerciale (ID client + référence de réservation) avant d'effectuer des effets secondaires. Chaque service de domaine doit valider cette clé par rapport à son Magasin d'Idempotence, implémenté comme une table PostgreSQL avec des contraintes uniques sur les clés composées ou des Filtres de Bloom dans Redis pour des recherches négatives économes en mémoire. Pour les sagas de longue durée, utilisez des Machines d'État de Saga avec un verrouillage optimiste via des vecteurs de version etcd pour gérer les sémantiques de traitement exactement une fois à travers des nœuds distribués. Cela empêche les scénarios de double réservation lorsque les groupes de consommateurs se rééquilibrent pendant les déploiements ou pendant les partitions réseau qui déclenchent des redémarrages de livenessProbe Kubernetes.