Partager via


Style d’architecture pilotée par les événements

Une architecture pilotée par les événements se compose de producteurs d’événements qui génèrent un flux d’événements, de consommateurs d’événements qui écoutent ces événements et de canaux d’événements (souvent implémentés en tant que répartiteurs d’événements ou services d’ingestion) qui transfèrent des événements des producteurs aux consommateurs.

Architecture

Diagramme montrant un style d’architecture piloté par les événements.

Les événements sont remis en quasi-temps réel, ce qui permet aux consommateurs de répondre immédiatement aux événements lorsqu’ils se produisent. Les producteurs sont découplés des consommateurs, ce qui signifie qu’un producteur ne sait pas quels consommateurs écoutent. Les consommateurs sont également découplés les uns des autres, et chaque consommateur voit tous les événements.

Ce processus diffère d’un modèle de consommateurs concurrents. Dans le modèle Consommateurs concurrents, les consommateurs extrayent les messages d’une file d’attente. Chaque message n’est traité qu’une seule fois, en supposant qu’il n’y a aucune erreur. Dans certains systèmes, tels qu’Azure IoT, les événements doivent être ingérés à des volumes élevés.

Une architecture pilotée par les événements peut utiliser un modèle de publication-abonnement ou un modèle de flux d’événements.

  • Publier-s’abonner : L’infrastructure de messagerie de publication-abonnement effectue le suivi des abonnements. Lorsqu’un événement est publié, il envoie l’événement à chaque abonné. Une fois l’événement remis, il ne peut pas être relecté et les nouveaux abonnés ne voient pas l’événement. Nous vous recommandons d’utiliser Azure Event Grid pour les scénarios de publication-abonnement.

  • Diffusion en continu d’événements : Les événements sont écrits dans un journal. Les événements sont strictement ordonnés dans une partition et sont durables. Les clients ne s’abonnent pas au flux. Au lieu de cela, un client peut lire n’importe quelle partie du flux. Le client est responsable de l’avancement de sa position dans le flux, ce qui signifie qu’un client peut rejoindre à tout moment et relire des événements. Azure Event Hubs est conçu pour la diffusion en continu d’événements à haut débit.

Côté consommateur, il existe quelques variantes courantes :

  • Traitement d’événements simple : Un événement déclenche immédiatement une action dans le consommateur. Par exemple, vous pouvez utiliser Azure Functions avec un déclencheur Event Grid ou un déclencheur Azure Service Bus afin que votre code s’exécute lorsqu’un message est publié.

  • Corrélation d’événements de base : Un consommateur traite quelques événements métier discrets, les met en corrélation par un identificateur et conserve les informations des événements antérieurs à utiliser lorsqu’il traite les événements ultérieurs. Les bibliothèques telles que NServiceBus et MassTransit prennent en charge ce modèle.

  • Traitement des événements complexes : Un consommateur utilise une technologie comme Azure Stream Analytics pour analyser une série d’événements et identifier des modèles dans les données d’événement. Par exemple, vous pouvez agréger des lectures à partir d’un appareil incorporé sur une fenêtre de temps et générer une notification si la moyenne mobile dépasse un seuil spécifique.

  • Traitement des flux d’événements : Utilisez une plateforme de diffusion en continu de données, telle qu’Azure IoT Hub, Event Hubs ou Event Hubs pour Apache Kafka, en tant que pipeline pour ingérer des événements et les alimenter vers des processeurs de flux. Les processeurs de flux agissent pour traiter ou transformer le flux. Il peut y avoir plusieurs processeurs de flux pour différents sous-systèmes de l’application. Cette approche convient parfaitement aux charges de travail IoT.

La source des événements peut être externe au système, comme les appareils physiques dans une solution IoT. Dans ce cas, le système doit pouvoir ingérer les données au niveau du volume et du débit requis par la source de données.

Il existe deux approches principales pour structurer les charges utiles d’événement. Lorsque vous contrôlez vos consommateurs d’événements, vous pouvez décider de la structure de charge utile pour chaque consommateur. Cette stratégie vous permet de combiner des approches selon les besoins au sein d’une seule charge de travail.

  • Incluez tous les attributs requis dans la charge utile : Utilisez cette approche lorsque vous souhaitez que les consommateurs disposent de toutes les informations disponibles sans avoir à interroger une source de données externe. Toutefois, il peut entraîner des problèmes de cohérence des données en raison de plusieurs systèmes d’enregistrement, en particulier après les mises à jour. La gestion des contrats et le contrôle de version peuvent également devenir complexes.

  • Incluez uniquement des clés dans la charge utile : Dans cette approche, les consommateurs récupèrent les attributs nécessaires, tels qu’une clé primaire, pour extraire indépendamment les données restantes d’une source de données. Cette méthode offre une meilleure cohérence des données, car elle possède un seul système d’enregistrement. Toutefois, elle peut s’effectuer moins bien que la première approche, car les consommateurs doivent interroger fréquemment la source de données. Vous avez moins de préoccupations concernant le couplage, la bande passante, la gestion des contrats ou le contrôle de version, car les événements plus petits et les contrats plus simples réduisent la complexité.

Dans le diagramme précédent, chaque type de consommateur s’affiche sous la forme d’une seule zone. Pour éviter que le consommateur devienne un point de défaillance unique dans le système, il est courant d’avoir plusieurs instances d’un consommateur. Plusieurs instances peuvent également être nécessaires pour gérer le volume et la fréquence des événements. Un seul consommateur peut traiter des événements sur plusieurs threads. Cette configuration peut créer des défis si les événements doivent être traités dans l’ordre ou nécessitent une sémantique exactement une fois. Pour plus d’informations, consultez Réduire la coordination.

Il existe deux topologies principales dans de nombreuses architectures pilotées par les événements :

  • Topologie broker : Les composants diffusent des événements sur l’ensemble du système. Les autres composants agissent sur l’événement ou ignorent l’événement. Cette topologie est utile lorsque le flux de traitement des événements est relativement simple. Il n’y a pas de coordination ou d’orchestration centrale, donc cette topologie peut être dynamique.

    Cette topologie est fortement découplée, ce qui permet de fournir une scalabilité, une réactivité et une tolérance de panne des composants. Aucun composant ne possède ou n’est conscient de l’état d’une transaction métier multistep et les actions sont effectuées de manière asynchrone. Par conséquent, les transactions distribuées sont risquées, car il n’existe aucun mécanisme intégré pour le redémarrage ou la relecture. Vous devez examiner attentivement la gestion des erreurs et les stratégies d’intervention manuelle, car cette topologie peut être une source d’incohérence des données.

  • Topologie du médiateur : Cette topologie traite certaines des lacunes de la topologie broker. Il existe un médiateur d’événements qui gère et contrôle le flux des événements. Le médiateur d’événement gère l’état et gère les fonctionnalités de gestion et de redémarrage des erreurs. Contrairement à la topologie broker, les composants de la topologie médiateur diffusent des occurrences sous forme de commandes, et uniquement aux canaux désignés. Ces canaux sont souvent des files d’attente de messages. Les consommateurs sont censés traiter ces commandes.

    Cette topologie offre un meilleur contrôle, une meilleure gestion des erreurs distribuées et une meilleure cohérence des données. Toutefois, cette topologie introduit un couplage accru entre les composants, et le médiateur des événements peut devenir un goulot d’étranglement ou une préoccupation de fiabilité.

Quand utiliser cette architecture

Vous devez utiliser cette architecture lorsque les conditions suivantes sont remplies :

  • Plusieurs sous-systèmes doivent traiter les mêmes événements.

  • Le traitement en temps réel avec un décalage de temps minimal est nécessaire.

  • Le traitement d’événements complexe, tel que la mise en correspondance de modèles ou l’agrégation au fil des fenêtres de temps, est requis.

  • Un volume élevé et une vitesse élevée des données sont nécessaires, par exemple avec IoT.

  • Vous devez dissocier les producteurs et les consommateurs pour des objectifs d’extensibilité et de fiabilité indépendants.

Avantages

Cette architecture offre les avantages suivants :

  • Les producteurs et les consommateurs sont découplés.
  • Il n’existe aucune intégration point à point. Il est facile d’ajouter de nouveaux consommateurs au système.
  • Les consommateurs peuvent répondre aux événements immédiatement lorsqu’ils se produisent.
  • Il est hautement évolutif, élastique et distribué.
  • Les sous-systèmes ont des vues indépendantes du flux d’événements.

Défis

  • Livraison garantie

    Dans certains systèmes, en particulier dans les scénarios IoT, il est essentiel de garantir la livraison des événements.

  • Traitement des événements dans l’ordre ou une seule fois

    Pour la résilience et la scalabilité, chaque type de consommateur s’exécute généralement dans plusieurs instances. Ce processus peut créer un défi si les événements doivent être traités dans l’ordre dans un type consommateur ou si la logique de traitement des messages idempotent n’est pas implémentée.

  • Coordination des messages entre les services

    Les processus métier ont souvent plusieurs services qui publient et s’abonnent aux messages pour obtenir un résultat cohérent dans l’ensemble d’une charge de travail. Vous pouvez utiliser des modèles de flux de travail tels que la chorégraphie et l’orchestration Saga pour gérer de manière fiable les flux de messages entre différents services.

  • Gestion des erreurs

    L’architecture pilotée par les événements repose principalement sur la communication asynchrone. Un défi courant que présente la communication asynchrone est la gestion des erreurs. Une façon de résoudre ce problème consiste à utiliser un processeur de gestionnaire d’erreurs dédié.

    Lorsqu’un consommateur d’événements rencontre une erreur, il envoie immédiatement et de manière asynchrone l’événement problématique au processeur du gestionnaire d’erreurs et continue de traiter d’autres événements. Le processeur du gestionnaire d’erreurs tente de résoudre le problème. S’il réussit, le processeur du gestionnaire d’erreurs resoumet l’événement au canal d’ingestion d’origine. En cas d’échec, le processeur peut transférer l’événement à un administrateur pour une inspection supplémentaire. Lorsque vous utilisez un processeur de gestionnaire d’erreurs, les événements renvoyés sont traités hors séquence.

  • Perte de données

    Un autre défi que présente la communication asynchrone est la perte de données. Si l’un des composants se bloque avant de traiter et de remettre l’événement à son composant suivant, l’événement est supprimé et n’atteint jamais la destination finale. Pour réduire le risque de perte de données, conservez les événements en transit et supprimez ou supprimez les événements uniquement lorsque le composant suivant accuse réception de l’événement. Ces fonctionnalités sont appelées mode accusé de réception du client et support du dernier participant.

  • Implémentation d’un modèle de demande-réponse traditionnel

    Parfois, le producteur d’événements nécessite une réponse immédiate du consommateur d’événements, par exemple obtenir l’éligibilité du client avant de passer une commande. Dans une architecture pilotée par les événements, la communication synchrone peut être obtenue à l’aide de la messagerie de demande-réponse.

    Ce modèle est implémenté avec une file d’attente de requêtes et une file d’attente de réponse. Le producteur d’événements envoie une requête asynchrone à une file d’attente de requêtes, interrompt d’autres opérations sur cette tâche et attend une réponse dans la file d’attente de réponse. Cette approche transforme efficacement ce modèle en processus synchrone. Les consommateurs d’événements traitent ensuite la demande et envoient la réponse par le biais d’une file d’attente de réponse. Cette approche utilise généralement un ID de session pour le suivi, afin que le producteur d’événements sache quel message dans la file d’attente de réponse est lié à la requête spécifique. La demande d’origine peut également spécifier le nom de la file d’attente de réponse, potentiellement éphémère, dans un en-tête de réponse à l’utilisateur ou un autre attribut personnalisé mutuellement convenu.

  • Maintenance du nombre approprié d’événements

    La génération d’un nombre excessif d’événements affinés peut saturer et submerger le système. Un volume excessif d’événements rend difficile l’analyse efficace du flux global des événements. Ce problème est aggravé lorsque les modifications doivent être restaurées. À l’inverse, la consolidation excessive des événements peut également créer des problèmes, ce qui entraîne un traitement et des réponses inutiles des consommateurs d’événements.

    Pour obtenir le bon équilibre, tenez compte des conséquences des événements et indiquez si les consommateurs doivent inspecter les charges utiles des événements pour déterminer leurs réponses. Par exemple, si vous disposez d’un composant de vérification de conformité, il peut suffire de publier seulement deux types d’événements : conformes et nonconformes. Cette approche permet de s’assurer que seuls les consommateurs pertinents traitent chaque événement, ce qui empêche le traitement inutile.

Autres considérations

  • La quantité de données à inclure dans un événement peut être une considération importante qui affecte les performances et les coûts. Vous pouvez simplifier le code de traitement et éliminer les recherches supplémentaires en plaçant toutes les informations pertinentes nécessaires au traitement directement dans l’événement. Lorsque vous ajoutez uniquement une quantité minimale d’informations à un événement, comme quelques identificateurs, vous réduisez le temps de transport et le coût. Toutefois, cette approche nécessite que le code de traitement récupère toutes les informations supplémentaires dont elle a besoin. Pour plus d’informations, consultez Mettre vos événements sur un régime alimentaire.

  • Une requête n’est visible que par le composant de gestion des demandes. Toutefois, les événements sont souvent visibles par plusieurs composants d’une charge de travail, même si ces composants ne les consomment pas ou ne sont pas destinés à les consommer. Pour travailler avec une mentalité de « violation de principe », gardez à l’esprit les informations que vous incluez dans les événements afin d’empêcher l’exposition involontaire d’informations.

  • De nombreuses applications utilisent l’architecture basée sur les événements comme architecture principale. Vous pouvez combiner cette approche avec d’autres styles architecturaux pour créer une architecture hybride. Les combinaisons classiques incluent les microservices et les canaux et les filtres. Intégrez une architecture pilotée par les événements pour améliorer les performances du système en éliminant les goulots d’étranglement et en fournissant une pression arrière pendant les volumes de demandes élevées.

  • Les domaines spécifiques couvrent souvent plusieurs producteurs d’événements, consommateurs ou canaux d’événements. Les modifications apportées à un domaine spécifique peuvent affecter de nombreux composants.

Étape suivante