Be Software Architecture Wise
Be Wise Apps

Read in English · Leer en español · Auf Deutsch lesen

Section 6.4 sur 6.8 · Avancé · 28 min de lecture

Architecture pilotée par les événements : courtiers, médiateurs et flux d’événements

Leçon vidéo

5 min · narré en anglais, avec sous-titres
Écouter seulement (audio)
Lire la transcription

Dans un système piloté par les événements, des parties annoncent ce qui s’est produit, et d’autres parties réagissent. Dans cette leçon, vous allez apprendre comment cela fonctionne, et comment le garder fiable quand des messages sont perdus ou répétés.

Pensez à la cuisine d’un restaurant très fréquenté. Un serveur accroche un bon de commande sur le rail, et personne ne reçoit d’ordre. Le cuisinier du grill voit un steak à cuire, le poste des salades voit une salade, et le pâtissier voit un dessert pour plus tard. Chacun réagit à son propre rythme. Si le pâtissier est en pause, le bon attend sur le rail jusqu’à son retour. Et ajouter un nouveau poste ne change pas la façon dont les serveurs rédigent les bons. Un système piloté par les événements fonctionne de la même façon.

Trois mots sont souvent employés de façon approximative. Un événement est un fait qui s’est produit, comme OrderPlaced. N’importe quel nombre de services peut le recevoir, et l’émetteur ne sait pas lesquels. Une commande est une demande adressée à un seul gestionnaire, comme AuthorisePayment. Contrairement à un événement, elle peut être refusée. Un message est simplement l’enveloppe qui transporte l’un ou l’autre. Une file remet chaque message à un seul consommateur, ce qui convient aux commandes. Un topic donne à chaque abonné sa propre copie, ce qui convient aux événements.

Voici la topologie à courtier, sans coordinateur central. Le service Commandes publie un événement OrderPlaced sur le topic orders, et poursuit son travail. Chaque service intéressé réagit à son rythme : Paiements autorise la carte, la tablette du restaurant affiche la commande, Notifications envoie une confirmation, et Analytique met à jour ses tableaux de bord. Paiements publie ensuite son propre événement, PaymentAuthorised, et Affectation réagit en affectant un livreur. Le flux de travail n’existe que comme la somme de ces réactions. C’est ce qu’on appelle la chorégraphie. Ajouter un service de détection de fraude l’an prochain ne demande qu’un nouvel abonnement, et aucun changement dans Commandes.

Dans la topologie à médiateur, un médiateur de commande dirige le flux de travail. Il connaît les étapes, leur ordre et ce qu’il faut faire en cas d’échec. C’est ce qu’on appelle l’orchestration. Il envoie des commandes à chaque service tour à tour, et agit selon leurs réponses. La chorégraphie couple le moins, mais l’ensemble du flux est difficile à voir. L’orchestration le rend visible, au risque de créer un goulot d’étranglement. La plupart des systèmes réels mélangent les deux.

Un courtier fondé sur un journal, comme Apache Kafka, conserve les événements, qu’ils aient été lus ou non. Un topic est divisé en partitions, chacune étant un journal ordonné, et chaque événement a une position appelée son offset. Les consommateurs rejoignent un groupe. Au sein d’un groupe, chaque partition n’est lue que par un seul consommateur à la fois, si bien que le groupe se partage le travail. Un autre groupe, comme celui de l’analytique, lit les mêmes événements de façon indépendante, avec ses propres offsets. Les événements de même clé, comme le numéro d’une commande, arrivent tous dans une seule partition, dans l’ordre. Mais l’ordre n’est garanti qu’au sein d’une partition, jamais entre partitions. Et comme chaque partition a un seul consommateur par groupe, le nombre de partitions limite le parallélisme. Douze partitions occupent au plus douze consommateurs d’un groupe.

Quand un plantage laisse planer un doute sur le traitement d’un message, il faut bien renoncer à quelque chose. Au plus une fois signifie jamais deux fois, mais parfois pas du tout. Cela convient pour les signaux de position des livreurs, où la mise à jour suivante remplace la précédente. Au moins une fois signifie jamais perdu, mais parfois traité deux fois. C’est le choix habituel pour les événements métier. La livraison exactement une fois sur un réseau non fiable n’est pas réalisable en général. Les systèmes ne peuvent offrir qu’un effet exactement une fois, à l’intérieur d’une frontière définie. Partez donc du principe d’une livraison au moins une fois, et rendez chaque consommateur idempotent. Donnez à chaque événement un identifiant unique, enregistrez les identifiants traités dans la même transaction locale que le changement, et ignorez ceux que vous avez déjà vus.

Dès que d’autres équipes consomment un événement, sa structure devient un contrat, et les consommateurs peuvent lire des événements écrits il y a des mois. Donnez à chaque événement un identifiant, un type, une version et un horodatage, et ne le modifiez que de façon compatible. Certaines défaillances sont temporaires, comme une base de données brièvement indisponible. Réessayez-les quelques fois, avec des délais croissants et aléatoires. D’autres échoueront à chaque fois, comme un événement mal formé. Ce message empoisonné ne doit pas bloquer sa partition. Déplacez-le vers une file de lettres mortes, et assurez-vous que quelqu’un la surveille. Et publiez des faits, pas des commandes déguisées. SendConfirmationEmail, publié sur un topic, est une commande dont le couplage est masqué. Publiez OrderPlaced, et laissez Notifications décider.

La section complète présente aussi quatre façons différentes d’utiliser les événements, et les schémas d’événements plus en détail. Ensuite, dans la section six point cinq, nous comparerons la communication synchrone et asynchrone, ainsi que la conception d’API. À très vite.

Ce qu’il faut savoir

Définition : réagir à ce qui se produit

Dans une architecture pilotée par les événements (EDA), les composants communiquent en produisant des événements et en y réagissant : des enregistrements de faits qui se sont produits dans l’activité, comme une commande a été passée ou un livreur a été affecté. Le composant qui publie un événement n’appelle pas les composants qui y réagissent et, en général, ne sait même pas qu’ils existent. Un courtier de messages (message broker) transporte les événements des producteurs vers les consommateurs, les conserve pendant que les consommateurs sont occupés ou indisponibles, et permet d’ajouter de nouveaux consommateurs sans modifier le producteur.

Les conceptions pilotées par les événements ne sont pas nouvelles : les interfaces graphiques, les systèmes d’exploitation et les systèmes de trading fonctionnent ainsi depuis des décennies, et les produits de messagerie d’entreprise sont antérieurs au web. Ce qui a changé dans les années 2010, c’est l’échelle et la durabilité. Les courtiers fondés sur un journal, comme Apache Kafka, créé chez LinkedIn et publié en open source en 2011, ont rendu possible de conserver chaque événement métier pendant des jours ou des années, et de les rejouer. L’EDA peut être le style principal d’un système ou, plus souvent, la façon dont les services d’un système en microservices ou à base de services communiquent entre eux.

Événements, commandes et messages

Trois mots sont souvent employés de façon approximative, et la différence compte. Un message est l’enveloppe : toute donnée envoyée d’un programme à un autre par un canal. Ce que transporte le message peut être un événement (un fait, nommé au passé), une commande (une demande adressée à un seul gestionnaire, nommée comme une instruction) ou une requête et sa réponse. Enterprise Integration Patterns (2003), de Gregor Hohpe et Bobby Woolf, a catalogué ces types de messages et les canaux qui les transportent, et son vocabulaire reste la référence.

Événement, commande et message

ÉvénementCommandeMessage (l’enveloppe)
SignificationUn fait : quelque chose qui s’est produitUne demande : merci de faire quelque choseToute donnée envoyée d’un programme à un autre par un canal
NommageAu passé : OrderPlaced, PaymentAuthorisedÀ l’impératif : AuthorisePayment, AssignCourierTransporte un événement, une commande, une requête ou une réponse
DestinatairesZéro, un ou plusieurs ; l’émetteur ne les connaît pasExactement un gestionnaire prévuDépend du canal : une file (un seul) ou un topic (plusieurs)
Peut-on le refuser ?Non ; il s’est déjà produit. Les destinataires décident comment réagirOui ; le gestionnaire peut la rejeter ou échouer à l’exécuterSans objet
CouplageL’émetteur ne dépend pas des consommateursL’expéditeur dépend de la capacité et du contrat du destinataireDépend de ce qu’il transporte

Les messages circulent par deux types de canaux. Une file remet chaque message à l’un de ses consommateurs, ce qui convient aux commandes et à la répartition du travail. Un topic remet une copie de chaque message à chaque abonné : c’est la publication-abonnement (publish-subscribe, ou pub-sub), qui convient aux événements. Une conception qui envoie OrderPlaced à un topic permet à Paiements, Restaurant, Notifications et Analytique de réagir, chacun à son rythme ; ajouter un service de détection de fraude l’an prochain ne demande qu’un nouvel abonnement et aucun changement dans Commandes.

Topologie à courtier et topologie à médiateur

Richards et Ford décrivent deux topologies pour les systèmes pilotés par les événements. Dans la topologie à courtier (broker), il n’y a pas de coordinateur central. Un événement initiateur est publié ; chaque processeur intéressé réagit et peut publier d’autres événements, auxquels d’autres réagissent à leur tour. Le flux de travail n’existe que comme la somme de ces réactions. C’est la chorégraphie : comme des danseurs qui connaissent chacun leurs propres pas, personne ne dirige l’ensemble.

Dans la topologie à médiateur, un médiateur d’événements reçoit l’événement initiateur et dirige le flux de travail, en envoyant des commandes aux processeurs dans un ordre défini et en agissant selon leurs réponses. C’est l’orchestration : un chef d’orchestre connaît la partition. Les médiateurs vont d’un simple service doté d’une machine à états à un moteur de workflow comme Temporal, AWS Step Functions ou un moteur BPMN.

Topologie à courtier : le flux OrderPlaced

Le flux OrderPlaced de la livraison de repas en topologie à courtier : Commandes publie OrderPlaced sur un topic orders ; Paiements, Restaurant, Notifications et Analytique le consomment chacun indépendamment ; Paiements publie PaymentAuthorised, que consomme Affectation pour affecter un livreurServiceCommandesCourtierorders(topic)payments(topic)OrderPlacedPaymentAuthorisedpubliePaiementsautoriser carteRestaurantafficher sur la tabletteNotificationsconfirmer au clientAnalytiqueMAJ des dashboardspublieAffect.affecter livreurPointillés : événements livrés aux abonnés. Chaque consommateur a sa propre copie et sa propre position.
En topologie à courtier, Commandes ne fait qu’annoncer le fait ; chaque consommateur réagit indépendamment, et c’est l’événement propre de Paiements qui déclenche l’étape suivante.

Topologie à médiateur : le même flux, orchestré

Topologie à médiateur : un médiateur de commande reçoit l’événement initiateur et envoie des commandes à Paiements, Restaurant, Affectation et Notifications dans un ordre défini, en recevant leurs réponsesClientpasse commandeMédiateurconnaît les étapeset leur ordre, etque faire en cas d’échecPaiements1 Autoriser paiementRestaurant2 Prévenir restaurantAffect.3 Affecter livreurNotifications4 Confirmer au clientCommandes émises ; réponses ouévénements renvoyés au médiateur
En topologie à médiateur, un seul composant détient la séquence : le flux de travail est donc visible et les défaillances sont gérées en un seul endroit.

Chorégraphie ou orchestration ?

QuestionChorégraphie (courtier)Orchestration (médiateur)
CouplageLe plus faible : les émetteurs ne connaissent pas les consommateursLe médiateur dépend du contrat de chaque participant
Voir l’ensemble du flux de travailDifficile : il est réparti entre les services ; il faut du traçage pour le reconstituerFacile : il est écrit en un seul endroit
Gestion des erreursChaque participant doit détecter les défaillances et y réagir, souvent en publiant des événements de compensationLe médiateur décide de façon centralisée des nouvelles tentatives, des délais d’expiration et des compensations
Ajouter une étapeAjouter un abonné ; rien d’autre ne changeModifier le médiateur
RisquesChaînes d’événements cycliques ; personne ne remarque quand une étape s’arrête silencieusementLe médiateur devient un goulot d’étranglement ou accumule de la logique métier
Bien adaptée àFlux simples et stables ; nombreuses réactions indépendantes à un même faitFlux de travail longs et conditionnels avec compensation, comme la saga de commande

La plupart des systèmes réels mélangent les deux : chorégraphie entre contextes délimités (Commandes annonce des faits et ne se soucie pas de savoir qui écoute) et orchestration à l’intérieur d’un contexte, là où un processus en plusieurs étapes a besoin d’un responsable clair.

Quatre façons d’utiliser les événements

Dans un article de 2017, Martin Fowler a souligné que « piloté par les événements » sert à désigner au moins quatre patrons assez différents, et que les conversations tournent mal quand les interlocuteurs ne parlent pas du même. Savoir les distinguer est l’une des habitudes les plus utiles qu’un architecte puisse avoir.

Les quatre patrons d’événements de Fowler (2017)

PatronCe que porte l’événement, et pourquoiAvantageCoût
Notification d’événementUn petit signal indiquant que quelque chose a changé, souvent un simple identifiant : OrderPlaced {order_id}. Les destinataires rappellent l’émetteur pour obtenir les détails s’ils en ont besoin.Couplage très faible ; le modèle de l’émetteur reste privé.Les rappels ajoutent de la charge et une dépendance à l’exécution envers l’émetteur ; le flux réparti sur de nombreux événements est difficile à voir.
Transfert d’état porté par les événements (event-carried state transfer)Assez de données pour que les destinataires conservent leur propre copie : la commande complète avec ses articles et ses totaux.Les destinataires fonctionnent sans appeler l’émetteur, même quand il est indisponible ; latence plus faible.Les données sont copiées largement et sont cohérentes à terme ; événements plus volumineux ; les schémas deviennent des contrats.
Event sourcingChaque changement de l’état d’une entité est stocké sous forme d’événement ; le journal des événements est la source de vérité et l’état courant est dérivé en le rejouant.Piste d’audit complète ; reconstitution des états passés ; nouvelles vues tirées de l’historique ancien.Complexe ; le rejeu est difficile quand les résultats dépendaient de systèmes externes ; les schémas d’événements doivent évoluer indéfiniment.
CQRSDes modèles séparés (souvent des stockages séparés) pour l’écriture et pour la lecture, fréquemment alimentés par des événements.Chaque côté est optimisé pour sa tâche ; convient aux systèmes très sollicités en lecture avec des requêtes complexes.Deux modèles à maintenir synchronisés ; souvent appliqué là où un seul modèle suffirait.

La notification d’événement et le transfert d’état porté par les événements concernent la communication entre services et ont leur place dans ce chapitre. L’event sourcing et CQRS concernent la façon dont un service stocke ses données ; on les combine souvent avec l’EDA, mais ce sont des choix indépendants, traités au chapitre 7.

Flux d’événements et journaux : comment fonctionne Kafka

Les files de messages traditionnelles suppriment un message dès qu’un consommateur l’a acquitté. Un courtier fondé sur un journal, comme Apache Kafka, stocke au contraire les événements dans un journal en ajout seul (append-only) et les conserve pendant une durée de rétention configurée (ou indéfiniment), qu’ils aient été lus ou non. Plusieurs conséquences découlent de cette conception, et elles expliquent à la fois les forces de Kafka et ses pièges.

Un topic est divisé en partitions, chacune étant un journal ordonné, stocké et répliqué sur plusieurs courtiers. Un producteur choisit la partition, normalement en hachant la clé de l’événement, si bien que tous les événements de même clé (le même identifiant de commande, par exemple) vont dans la même partition. Chaque événement d’une partition a une position séquentielle appelée son offset (décalage). Les consommateurs tirent les événements et enregistrent l’offset qu’ils ont atteint ; ils peuvent aussi revenir en arrière et rejouer.

Les consommateurs rejoignent un groupe de consommateurs. Au sein d’un groupe, chaque partition est lue par un seul consommateur à la fois, si bien que le groupe se partage le travail ; des groupes différents lisent indépendamment, chacun avec ses propres offsets, et c’est ainsi que l’on obtient le pub-sub. Le nombre de partitions limite donc le parallélisme d’un groupe : un topic de 12 partitions peut occuper au plus 12 consommateurs d’un groupe. (Kafka 4.2, publié en 2026, a ajouté les share groups comme alternative de type file : plusieurs consommateurs peuvent se partager une partition et acquitter les messages individuellement, mais l’ordre au sein de la partition n’est alors plus préservé. Cette section décrit les groupes de consommateurs classiques.)

Kafka ne garantit l’ordre qu’au sein d’une partition. Les événements d’une même commande arrivent dans l’ordre où ils ont été écrits s’ils partagent une clé ; les événements de commandes différentes, dans des partitions différentes, n’ont aucun ordre défini les uns par rapport aux autres. Les conceptions qui ont besoin d’un ordre global doivent utiliser une seule partition (en renonçant au parallélisme) ou, mieux, être repensées pour que seul l’ordre par entité compte.

Partitions, offsets et groupes de consommateurs

Un topic à trois partitions, chacune un journal en ajout seul aux offsets numérotés ; le groupe payments répartit les partitions entre deux consommateurs, tandis que le groupe analytics lit les trois avec un seul consommateurTopic order-events, 3 partitions (clé = ID de commande)P0012345P1012345P2012345offsets : 0, 1, 2 ... nouveaux événements ajoutés à droiteGroupe : paymentsConsomm. Alit P0, P1Consomm. Blit P2Groupe : analyticsConsomm. Clit P0, P1, P2Ordre garanti dans une partitiontous les événements de la commande 4711 ont lamême clé : même partition, dans l’ordreGroupes indépendantschaque groupe garde ses offsets validés ;dans un groupe, un consommateur par partition
Chaque partition est un journal ordonné ; un groupe de consommateurs répartit les partitions entre ses membres, et chaque groupe suit ses propres offsets.

Garanties de livraison, et ce que signifie vraiment « exactement une fois »

Comme les réseaux et les processus tombent en panne (section 6.1), un courtier et ses clients doivent choisir ce qui se passe lorsqu’un plantage ou un délai d’expiration laisse planer un doute sur le traitement d’un message. Il existe trois garanties possibles, et le choix dépend du moment où les acquittements et les offsets sont enregistrés.

Garanties de livraison

GarantieCe qu’elle prometComment on l’obtientConséquence typique
Au plus une fois (at-most-once)Chaque message est traité une fois ou pas du tout ; jamais deux fois.Le consommateur enregistre sa position (valide l’offset ou acquitte) avant le traitement, ou le producteur ne fait jamais de nouvelle tentative.Des messages peuvent être perdus après un plantage. Acceptable pour des échantillons de métriques ou des signaux de position des livreurs, où la mise à jour suivante remplace la précédente.
Au moins une fois (at-least-once)Chaque message est traité une ou plusieurs fois ; jamais perdu.Le producteur réessaie jusqu’à l’acquittement, et le consommateur ne valide sa position qu’après le traitement.Des doublons après les plantages, les nouvelles tentatives et les rééquilibrages. C’est le comportement par défaut de la plupart des courtiers et le choix habituel pour les événements métier.
Effectivement une fois (effectively-once)L’effet de chaque message est appliqué exactement une fois, même s’il peut être livré plus d’une fois.Une livraison au moins une fois associée à un consommateur idempotent, ou une transaction qui enregistre ensemble le résultat et la position du consommateur.Le sens pratique de « exactement une fois » dans les systèmes métier ; exige une conception délibérée dans chaque consommateur.

« Exactement une fois » demande une définition rigoureuse. La livraison exactement une fois sur un réseau non fiable n’est pas réalisable en général : un expéditeur qui ne reçoit pas d’acquittement ne peut pas savoir s’il doit renvoyer le message. Ce que les systèmes peuvent offrir, c’est un effet exactement une fois à l’intérieur d’une frontière définie. Kafka, par exemple, propose un producteur idempotent et des transactions depuis la version 0.11 (2017), afin qu’un cycle lecture-traitement-écriture allant de topics Kafka vers des topics Kafka valide sa sortie et les offsets de son consommateur de façon atomique. Cette garantie s’arrête à la frontière de Kafka. Si le consommateur débite une carte, envoie un e-mail ou écrit dans une autre base de données, un plantage entre cette action et la validation de l’offset entraînera la répétition de l’action, à moins que le consommateur lui-même soit idempotent ou qu’il stocke ses offsets dans la même transaction que ses résultats.

La règle pratique pour les architectes est donc simple : partez du principe d’une livraison au moins une fois et faites de chaque consommateur un consommateur idempotent. Donnez à chaque événement un identifiant unique ; dans le consommateur, enregistrez les identifiants traités dans la même transaction locale que le changement d’état, et ignorez tout événement déjà enregistré. Dans la mesure du possible, rendez aussi l’opération naturellement idempotente, par exemple « passer le statut à PAID s’il est AWAITING_PAYMENT » plutôt que « ajouter un paiement ».

# Idempotent consumer: processing the same event twice has the effect of once
def handle_payment_authorised(event, db):
    with db.transaction():                       # one local ACID transaction
        inserted = db.execute(
            "INSERT INTO processed_events (event_id) VALUES (%s) "
            "ON CONFLICT (event_id) DO NOTHING",
            [event["event_id"]],
        ).rowcount
        if inserted == 0:
            return                               # seen before: do nothing
        db.execute(
            "UPDATE orders SET status = 'PAID' WHERE order_id = %s "
            "AND status = 'AWAITING_PAYMENT'",
            [event["order_id"]],
        )
    # commit the broker offset only after the transaction has committed
Un consommateur idempotent : l’enregistrement des événements traités et le changement d’état sont validés ensemble, si bien qu’un événement relivré ne change rien.

Schémas d’événements et versionnage

Dès que d’autres équipes consomment un événement, sa structure est un contrat publié, exactement comme une API, et elle dure plus longtemps : avec un courtier fondé sur un journal, les consommateurs peuvent lire des événements écrits il y a des mois. Un bon événement comporte un identifiant unique, un type, une version de schéma, l’heure à laquelle il s’est produit, les identifiants des entités concernées et les données métier dont les consommateurs ont besoin. Les montants sont stockés en unités mineures avec une devise, jamais sous forme de nombre à virgule flottante (chapitre 0).

{
  "event_id": "9f1c2e7a-4b0d-4e55-9a51-0c3d8f2b6a10",
  "type": "OrderPlaced",
  "schema_version": 2,
  "occurred_at": "2026-10-22T18:42:07Z",
  "order_id": "ord-4711",
  "customer_id": "cus-208",
  "restaurant_id": "res-31",
  "items": [{"dish_id": "d-5", "qty": 2, "price_minor": 1150}],
  "total_minor": 2450,
  "currency": "GBP"
}
Un événement OrderPlaced qui utilise le transfert d’état porté par les événements : identifiants, version, heure et données dont les consommateurs ont besoin.

Les schémas doivent évoluer de façon rétrocompatible : ajouter des champs optionnels, ne jamais supprimer ni renommer des champs ni changer leur signification sans nouvelle version, et ne jamais réutiliser un nom de champ pour autre chose. De nombreuses équipes l’imposent avec un format de schéma comme Avro, Protocol Buffers ou JSON Schema et un registre de schémas qui rejette les changements incompatibles au moment de la publication. La spécification CloudEvents, projet de niveau « graduated » de la Cloud Native Computing Foundation, normalise les attributs d’enveloppe courants comme id, source, type et time. Les modes de compatibilité et les techniques de migration sont traités dans évolution des schémas.

Gestion des erreurs : nouvelles tentatives, messages empoisonnés et files de lettres mortes

Les consommateurs échouent pour deux raisons très différentes, qui demandent des traitements différents. Les défaillances transitoires, comme une base de données brièvement indisponible ou un délai d’expiration lors de l’appel d’un autre service, réussissent généralement après une nouvelle tentative ; réessayez quelques fois avec un backoff exponentiel et du jitter (des délais croissants et aléatoires) afin de ne pas submerger une dépendance en difficulté. Les défaillances permanentes, comme un événement mal formé ou qui viole une règle métier, échoueront à chaque fois. Un tel « message empoisonné » (poison message) ne doit pas bloquer le consommateur indéfiniment, ce qui, sur un journal partitionné, bloquerait tous les événements suivants de cette partition.

La réponse standard est une file de lettres mortes (dead-letter queue, DLQ) : après un nombre défini de tentatives, le message est déplacé vers un canal distinct, avec l’erreur enregistrée, et le consommateur passe à la suite. Une DLQ n’est utile que si quelqu’un la surveille : déclenchez des alertes sur sa taille, confiez-en la responsabilité à une équipe nommément désignée, fournissez des outils pour inspecter, corriger et rejouer les messages, et décidez à l’avance quelles garanties d’ordre sont perdues lorsqu’un message est rejoué tardivement. Certaines équipes ajoutent un ou plusieurs topics intermédiaires de nouvelle tentative, avec des délais plus longs, avant la DLQ.

Caractéristiques de l’architecture pilotée par les événements

CaractéristiqueÉvaluationRaison
Scalabilité et élasticitéÉlevéeLes consommateurs passent à l’échelle indépendamment et absorbent les pics grâce au tampon du courtier ; les partitions permettent le parallélisme.
RéactivitéÉlevéeL’émetteur rend la main dès que l’événement est enregistré de façon durable ; le travail lent se fait plus tard.
Tolérance aux pannesÉlevéeUn consommateur peut être indisponible pendant des minutes puis rattraper son retard depuis le courtier ; les défaillances ne remontent pas en cascade jusqu’à l’émetteur.
ExtensibilitéÉlevéeDe nouveaux consommateurs s’abonnent aux événements existants sans aucun changement chez l’émetteur.
Cohérence des donnéesFaibleL’état se propage entre services avec un délai ; les lecteurs voient des données périmées pendant un certain temps.
Testabilité et débogabilitéFaibleLe comportement émerge de réactions asynchrones ; reproduire une séquence d’événements à travers les services est difficile sans un bon traçage.
Visibilité du flux de travailFaible (chorégraphie) à moyenne (médiateur)Personne ne détient le flux de bout en bout en chorégraphie ; un médiateur le rend explicite.
SimplicitéFaibleCourtiers, schémas, nouvelles tentatives, traitement des lettres mortes, ordre et doublons doivent tous être conçus.

Quand l’utiliser, et erreurs courantes

L’architecture pilotée par les événements convient quand de nombreuses parties d’une activité doivent réagir aux mêmes faits, quand le travail peut se faire après le retour de la requête de l’utilisateur, quand la charge arrive par à-coups et doit être lissée, et quand de nouveaux consommateurs sont attendus au fil du temps. Elle convient moins bien quand un utilisateur a besoin d’une réponse immédiate et définitive qui dépend de plusieurs services (même si un appel synchrone pour la réponse, complété par des événements pour la suite, est un hybride courant), ou quand une forte cohérence entre services est requise.

Vérifiez votre compréhension

ReserveCourier est-il un événement ou une commande, et comment le savoir ?

Une commande : c’est une instruction adressée à un seul gestionnaire (Affectation), qui peut la refuser. Un événement serait nommé au passé, comme CourierReserved.

Un topic Kafka a 6 partitions et un groupe de consommateurs compte 10 consommateurs. Combien de consommateurs seront occupés ?

Au plus 6. Au sein d’un groupe, chaque partition est attribuée à un seul consommateur : 4 consommateurs restent donc inactifs.

Pourquoi la prise en charge de l’exactement une fois par Kafka n’empêche-t-elle pas un consommateur d’envoyer deux fois un e-mail de confirmation ?

Ses transactions couvrent la lecture et l’écriture dans des topics Kafka ainsi que la validation des offsets ; un e-mail envoyé à un système externe est hors de cette frontière, si bien qu’un plantage avant la validation de l’offset entraîne un nouveau traitement, à moins que le consommateur soit idempotent.

Quelle est la différence entre la notification d’événement et le transfert d’état porté par les événements ?

La notification envoie un petit signal, souvent un simple identifiant, si bien que les destinataires rappellent l’émetteur pour obtenir les détails ; le transfert d’état inclut les données dont les destinataires ont besoin, ce qui leur permet de conserver leur propre copie et d’éviter d’appeler l’émetteur.

Suivant · 6.5Communication et APIComment les services dialoguent : le couplage créé par la communication synchrone et asynchrone, la sémantique de REST et de HTTP, gRPC, GraphQL et la messagerie, et les pratiques de conception d’API qui permettent aux interfaces d’évoluer sans casser les consommateurs.Continuer →

Sources et lectures complémentaires

Une question sur cette section ? ArchitectBot, l’assistant d’étude IA du cours, répond d’abord à partir du cours.

Demander : « Nos événements de commande passent par Kafka et certains clients reçoivent parfois deux e-mails de confirmation. Que se passe-t-il, et comment devrions-nous concevoir le consommateur ? »