Les initiatives de modernisation des entreprises nécessitent de plus en plus l'intégration d'infrastructures IBM MQ et TIBCO vieilles de plusieurs décennies avec Apache Kafka et AWS EventBridge sans réécriture des mainframes COBOL hérités. Les services financiers exigent spécifiquement des sémantiques exactement une fois pour les commandes de trading où l'exécution en double constitue un risque matériel et une violation réglementaire.
Les bus de messages hérités manquent de primitives d'idempotence natives et reposent sur un ordre FIFO impératif avec des lectures destructrices, tandis que les flux cloud-natifs favorisent des journaux immuables avec des replays basés sur des offsets. Le décalage d'impédance de protocole — des copies COBOL à largeur fixe par rapport à des données Avro autodécrivant — combiné avec des garanties de livraison hétérogènes crée des vecteurs de perte ou de duplication de messages lors des événements d'échelle des adaptateurs ou des partitions réseau transitoires.
Déployer des pods d'Adaptateur de protocole sans état exécutant Apache Camel ou Spring Cloud Stream au sein de Kubernetes pour médiatiser entre les systèmes. Implémenter le modèle de Consommateur idempotent en utilisant Redis ou Amazon DynamoDB pour suivre les UUIDs de messages traités avec expiration TTL. Utiliser les Transactions Kafka avec des niveaux d'isolation read_committed pour garantir des engagements atomiques d'offset et de production de message. Autoscaler les adaptateurs en utilisant KEDA (Autoscaling piloté par événement Kubernetes) basé sur les métriques de profondeur de file d'attente IBM MQ exportées via Prometheus. Isoler les messages indésirables dans des Files de lettres mortes (DLQ) implémentées dans Amazon SQS ou Apache Pulsar pour éviter le blocage de tête de ligne.
Une banque d'investissement de premier plan devait migrer des flux d'exécution de trading en temps réel d'un mainframe z/OS exécutant IBM MQ vers AWS MSK (Kafka) sans temps d'arrêt. Le système hérité publiait des messages encodés avec une copie de livre COBOL représentant des ordres d'achat/vente, tandis que les microservices modernes en Java consommaient des événements sérialisés en Avro. Pendant la volatilité du marché, les taux de messages ont grimpé à 50 000 TPS, ce qui a provoqué l'abandon de messages lors de la mise en œuvre initiale du pont en raison de tailles de tampon TCP insuffisantes et d'un manque de contre-pression.
Solution 1 : Écriture double avec réconciliation. Cette approche modifie le mainframe pour écrire à la fois dans IBM MQ et Apache Kafka simultanément, suivie de travaux de réconciliation nocturnes pour corriger les écarts. Les avantages incluent des changements d'infrastructure minimaux et des délais de mise en œuvre rapides. Les inconvénients incluent la violation des sémantiques exactement une fois pendant les transactions intrajournalières, le décalage de réconciliation créant des problèmes d'audit réglementaire, et des interventions manuelles nécessaires pour la résolution des conflits qui violent les SLO d'automatisation.
Solution 2 : Stocker-et-transmettre avec des transactions XA. Mettre en œuvre WebSphere MQ en tant que gestionnaire de ressources X/Open XA coordonnant avec des producteurs transactionnels Kafka à travers des frontières de contrat en deux phases. Les avantages offrent une forte cohérence via des protocoles d'engagement atomique. Les inconvénients incluent des verrouillages détenus pendant des millisecondes sur des liens WAN lors de la réplication inter-régionale, un comportement de blocage violant les SLO de latence inférieure à 100 ms, et une incompatibilité du pilote XA avec les offres Kafka gérées comme AWS MSK.
Solution 3 : Ponts de protocole sans état avec dé-duplication externalisée. Déployer des ponts Apache Camel en tant que déploiements Kubernetes, transformant COBOL en Avro à l'aide de parseurs JRecord dynamiques avec vérifications d'UUID uniques contre DynamoDB avant de produire à Kafka. KEDA évolue les pods en fonction de la profondeur de la file d'attente signalée par les commandes MQSC. Les avantages incluent une architecture évolutive horizontale non bloquante et exactement une fois via idempotence plutôt que transactions distribuées. Les inconvénients nécessitent une maturité opérationnelle pour la planification de capacité DynamoDB et la surveillance des itinéraires Camel.
Solution choisie et résultat. La solution 3 a été sélectionnée pour maintenir une latence de bout en bout inférieure à 50 ms. Lors d'un test de stress simulant le volume de trading du Black Friday, le système a traité 2,5 millions de messages sans doublon et sans perte. Lorsque des messages mal formés sont apparus (champs CUSIP obligatoires manquants), le Circuit Breaker (Resilience4j) s'est ouvert, détournant les mauvais messages vers une DLQ Amazon SQS tout en permettant aux transactions légitimes de s'écouler, évitant ainsi l'arriéré catastrophique rencontré lors des premiers pilotes.
Comment maintenez-vous des sémantiques exactement une fois lorsque le MQ hérité manque de dé-duplication des messages et que les consommateurs Kafka peuvent re-traiter des messages en raison d'échecs de validation des offsets ?
Les candidats proposent souvent des producteurs idempotents Kafka seuls, ce qui ne résout que la dé-duplication au sein de Kafka, pas à travers la frontière MQ-à-Kafka. L'approche correcte combine le modèle Outbox sur le système source — où le mainframe écrit des messages dans une table de sortie au sein de sa base de données DB2 transactionnellement, puis un connecteur CDC (Change Data Capture) comme Debezium diffuse les changements vers Kafka — avec un stockage de dé-duplication (Redis SETNX ou écritures conditionnelles DynamoDB) du côté consommateur. Le consommateur écrit l'UUID dans le stockage de manière atomique avec l'exécution de la logique métier à l'aide de transactions de base de données locales, garantissant l'idempotence même pendant les rééquilibrages de consommateur ou la réaffectation de partition.
Comment gérez-vous l'évolution du schéma de copie COBOL sans redéployer le pont de l'adaptateur de protocole ?
La plupart des candidats proposent une génération de code statique à partir des copies de livres COBOL en utilisant des outils comme CB2XML, nécessitant un redéploiement pour chaque changement de schéma. Une solution robuste utilise la Résolution de Schéma à l'Exécution : stocker les définitions de copies de livre dans Git ou AWS S3, référencées par un ID de version dans les en-têtes de message. Le chemin Apache Camel utilise JRecord avec un chargement de classe dynamique pour analyser les messages en fonction des versions de schéma spécifiées dans les en-têtes. Combinez cela avec le ConfigMap de Kubernetes ou le AWS AppConfig pour un rechargement à chaud des schémas sans redémarrages de pod. Cela découple les cycles de publication de mainframe des pipelines de déploiement cloud.
Comment éviter que la file d'attente MQ héritée n'atteigne une profondeur maximale pendant une panne prolongée de la destination cloud, étant donné que MQ a un stockage fini ?
Les candidats suggèrent souvent un stockage infini ou une expansion de disque MQ, ce qui ne fait que retarder l'inévitable. La stratégie correcte implémente la Contre-pression et le Déchargement : configurez IBM MQ Application Message Routing ou MQIPT (MQ Internet Pass-Thru) pour déclencher des alarmes de seuil lorsque la profondeur de la file d'attente dépasse 80 %. Le pont cesse de lire (appliquant une contre-pression) et passe au mode Stocker-et-transmettre, écrivant les messages entrants dans Amazon S3 ou Azure Blob Storage en tant que fichiers sérialisés. Une fois la connectivité rétablie, un conteneur Sidecar rejoue les objets S3 dans Kafka en utilisant les téléchargements multipartiels AWS SDK, drainant l'arriéré sans épuisement du disque MQ ni perte de message.