Partager via


Conception résiliente d’Event Hubs et d’Azure Functions

La gestion des erreurs, la conception pour l’idempotence et la gestion du comportement de nouvelle tentative sont quelques-unes des mesures critiques que vous pouvez prendre pour garantir que les fonctions déclenchées Event Hubs sont résilientes et capables de gérer de gros volumes de données. Cet article aborde ces concepts cruciaux et fournit des recommandations pour les solutions de streaming d’événements serverless.

Azure fournit trois services de messagerie principaux qui peuvent être utilisés avec Azure Functions pour prendre en charge un large éventail de scénarios uniques et pilotés par les événements. En raison de son modèle de consommateur partitionné et de sa capacité à ingérer des données à un débit élevé, Azure Event Hubs est couramment utilisé pour le streaming d’événements et les scénarios Big Data. Pour une comparaison détaillée des services de messagerie Azure, consultez Choisir entre les services de messagerie Azure : Event Grid, Event Hubs et Service Bus.

Avantages et défis liés au streaming

Comprendre les avantages et les inconvénients des flux vous aide à apprécier le fonctionnement d’un service comme Event Hubs. Vous avez également besoin de ce contexte pour prendre des décisions architecturales percutantes, résoudre les problèmes et optimiser les performances. Tenez compte des concepts clés suivants concernant les solutions qui incluent à la fois Event Hubs et Azure Functions :

  • Les flux ne sont pas des files d’attente : Event Hubs, Kafka et d’autres offres similaires reposant sur le modèle de consommateur partitionné ne prennent pas intrinsèquement en charge certaines des fonctionnalités principales d’un courtier de messages comme Service Bus. L’indicateur le plus important de ces différences est peut-être le fait que les lectures ne sont pas destructrices. Cela garantit que les données lues par l’hôte Functions restent disponibles par la suite. Au lieu de cela, les messages sont immuables et les autres consommateurs ont la possibilité de les lire. Il se peut même que le même consommateur les relisent plusieurs fois. C’est pourquoi les solutions qui implémentent des modèles tels que les consommateurs concurrents peuvent être mieux servies avec un répartiteur de messages tel que Service Bus.

  • Prise en charge des lettres mortes inhérentes absente : un canal de lettres mortes n’est pas une fonctionnalité native d’Event Hubs ou de Kafka. Souvent, le concept de lettres mortes est intégré à une solution de streaming pour tenir compte des données qui ne peuvent pas être traitées. Cette fonctionnalité n’est intentionnellement pas un élément inné dans Event Hubs et est uniquement ajoutée côté client pour fabriquer un comportement ou un effet similaire. Si vous avez besoin d’une prise en charge des lettres mortes, vous devez éventuellement revoir votre choix de service de streaming de messages.

  • Une unité de travail est une partition : Dans un courtier de messages traditionnel, une unité de travail est un message unique. Dans une solution de streaming, une partition est souvent considérée comme une unité de travail. Si chaque événement d’un hub d’événements est traité comme un message distinct nécessitant le traitement d’une commande ou d’une transaction financière, cela suggère la possibilité d’explorer un service de messagerie plus approprié pour une performance ou un traitement optimal.

  • Aucun filtrage côté serveur : l’une des raisons pour lesquelles Event Hubs est susceptible de bénéficier d’une mise à l’échelle et d’un débit considérables est due à la faible surcharge du service lui-même. Les fonctionnalités telles que le filtrage côté serveur, les index et la coordination entre courtiers ne font pas partie de l’architecture d’Event Hubs. Les fonctions sont parfois utilisées pour filtrer les événements en les acheminant vers d’autres Event Hubs en fonction du contenu du corps ou de l’en-tête. Cette approche est courante dans le streaming d’événements, mais l’inconvénient est que chaque événement est lu et évalué par la fonction initiale.

  • Chaque lecteur doit lire toutes les données : étant donné que le filtrage côté serveur n’est pas disponible, un consommateur lit séquentiellement toutes les données d’une partition. Cela inclut les données qui peuvent ne pas être pertinentes ou peuvent même être incorrectes. Il existe plusieurs options et stratégies qui peuvent être utilisées pour compenser les défis qui sont abordés plus loin dans cette section.

Ces importantes décisions en matière de conception permettent à Event Hubs de faire ce qu’il fait le mieux : prendre en charge un flux important d’événements et fournir un service robuste et résilient offrant des fonctionnalités de lecture aux consommateurs. Chaque application cliente est chargée de conserver ses propres décalages côté client ou curseur à ces événements. La faible surcharge fait d’Event Hubs une option abordable et puissante pour le streaming d’événements.

Idempotence

L’un des principes d’Azure Event Hubs est le concept de remise au moins une fois. Cette approche garantit que les événements sont toujours remis. Cela signifie également que les événements peuvent être reçus plusieurs fois, même de manière répétée, par des consommateurs, par exemple une fonction. Pour cette raison, il est important qu’une fonction déclenchée par Event Hub prenne en charge le modèle de consommateur idempotent.

Se baser sur l’hypothèse d’une remise au moins une fois, en particulier dans le contexte d’une architecture pilotée par les événements, est une approche responsable pour le traitement fiable des événements. Votre fonction doit être idempotente, de sorte que le résultat du traitement du même événement à plusieurs reprises est le même que celui du traitement une seule fois.

Événements en double

Il existe plusieurs scénarios qui peuvent entraîner la remise d’événements en double à une fonction :

  • Point de contrôle : si l’hôte Azure Functions se bloque ou si le seuil défini pour la fréquence du point de contrôle de lot n’est pas respecté, aucun point de contrôle n’est créé. Par conséquent, le décalage pour le consommateur n’est pas avancé et lors du prochain appel de la fonction, celle-ci reprend à partir du dernier point de contrôle. Il est important de noter que les points de contrôle se produisent au niveau de la partition pour chaque consommateur.

  • Événements en double publiés : de nombreuses techniques peuvent réduire les chances que le même événement soit publié sur un flux, mais le consommateur est toujours responsable de la gestion des doublons de façon idempotente.

  • Accusés de réception manquants : dans certains cas, une demande sortante vers un service peut réussir alors qu’aucun accusé de réception (ACK) du service n’est reçu. Cela peut donner l’impression que l’appel sortant a échoué et initier une série ou de nouvelles tentatives ou d’autres résultats de la fonction. À la fin, des événements en double peuvent être publiés ou aucun point de contrôle n’est créé.

Techniques de déduplication

La conception de vos fonctions pour une entrée identique doit être l’approche par défaut prise en association avec la liaison de déclencheur Event Hub. Vous devez envisager les techniques suivantes :

  • Recherche de doublons : avant le traitement, effectuez les étapes nécessaires pour confirmer que l’événement doit être traité. Dans certains cas, cette opération nécessite une investigation pour confirmer qu’il est toujours valide. Il est également possible que la gestion de l’événement ne soit plus nécessaire en raison de l’actualisation des données ou de la logique qui invalide l’événement.

  • Concevoir des événements pour idempotence : en fournissant des informations supplémentaires dans la charge utile de l’événement, il est possible de s’assurer que le traitement à plusieurs reprises n’a aucun effet négatif. Prenons l’exemple d’un événement qui inclut un montant à retirer d’un compte bancaire. S’il n’est pas géré de manière responsable, il est possible qu’il décrémente plusieurs fois le solde d’un compte. Toutefois, si le même événement inclut le solde mis à jour sur le compte, il peut être utilisé pour effectuer une opération upsert sur le solde du compte bancaire. Cette approche de transfert d’état effectué par un événement nécessite parfois une coordination entre les producteurs et les consommateurs, et doit être utilisée lorsque cela est judicieux pour les services participants.

Gestion des erreurs et nouvelles tentatives

La gestion des erreurs et les nouvelles tentatives sont quelques-unes des qualités les plus importantes des applications distribuées, pilotées par les événements, et les fonctions ne font pas exception. Pour les solutions de streaming d’événements, la nécessité d’une prise en charge appropriée de la gestion des erreurs est cruciale, car des milliers d’événements peuvent rapidement se transformer en erreurs s’ils ne sont pas gérés correctement.

Conseil de gestion des erreurs

Sans la gestion des erreurs, il peut être difficile d’implémenter les nouvelles tentatives, de détecter les exceptions au moment de l’exécution et d’examiner les problèmes. Chaque fonction doit avoir un certain niveau de gestion des niveaux ou des erreurs. Voici quelques recommandations :

  • Utiliser Application Insights : activez et utilisez Application Insights pour journaliser les erreurs et surveiller l’intégrité de vos fonctions. Gardez à l’esprit les options d’échantillonnage configurables pour les scénarios qui traitent un volume élevé d’événements.

  • Ajouter une gestion structurée des erreurs : appliquez les constructions de gestion des erreurs appropriées pour chaque langage de programmation afin d’intercepter, de journaliser et de détecter les exceptions attendues et non gérées dans le code de votre fonction. Par exemple, utilisez un bloc try/catch en C#, Java et JavaScript et tirez parti des blocs try et except dans Python pour gérer les exceptions.

  • Journalisation : l’interception d’une exception pendant l’exécution offre la possibilité de journaliser des informations critiques qui pourraient être utilisées pour détecter, reproduire et résoudre les problèmes de manière fiable. Consignez l’exception, pas seulement le message, mais le corps, l’exception interne et d’autres artefacts utiles qui seront utiles ultérieurement.

  • Ne pas intercepter et ignorer les exceptions : l’une des pires choses que vous pouvez faire est d’intercepter une exception et de ne rien faire avec celle-ci. Si vous interceptez une exception générique, journalisez-la quelque part. Si vous ne journalisez pas les erreurs, il est difficile d’examiner les bogues et les problèmes signalés.

Nouvelle tentatives

L’implémentation d’une logique de nouvelle tentative dans une architecture de streaming d’événements peut être complexe. La prise en charge des jetons d’annulation, les quantités de nouvelles tentatives et les stratégies d’interruption exponentielles sont quelques-uns des éléments qui la rendent difficile. Heureusement, Azure Functions fournit des stratégies de nouvelle tentative qui peuvent remplacer un grand nombre de ces tâches que vous codez généralement vous-même.

Voici plusieurs facteurs importants à prendre en compte lors de l’utilisation de stratégies de nouvelle tentative avec la liaison Event Hub :

  • Éviter un nombre indéfini de nouvelles tentatives : lorsque le paramètre Nombre maximal de nouvelles tentatives est défini sur la valeur -1, la fonction réessaie indéfiniment. En général, les nouvelles tentatives indéfinies doivent être utilisées avec modération avec Azure Functions et presque jamais avec la liaison de déclencheur Event Hub.

  • Choisir la stratégie de nouvelle tentative appropriée : une stratégie de délai fixe peut être optimale pour les scénarios qui reçoivent une pression des autres services Azure. Dans ce cas, le délai peut aider à éviter la limitation et d’autres limitations de ces services. La stratégie dinterruption exponentielle offre plus de flexibilité pour les intervalles de délai entre les nouvelles tentatives et est couramment utilisée lors de l’intégration à des services tiers, des points de terminaison REST et d’autres services Azure.

  • Conserver un petit nombre d’intervalles et de nouvelles tentatives faible : dans la mesure du possible, essayez de maintenir un intervalle de nouvelle tentative inférieur à une minute. De même, définissez le nombre maximal de nouvelles tentatives sur un nombre raisonnablement faible. Ces paramètres sont particulièrement pertinents lors de l’exécution dans le plan de consommation Azure Functions.

  • Modèle disjoncteur : une erreur temporaire est attendue de temps à autre et un cas d’usage naturel est attendu pour les nouvelles tentatives. Toutefois, si un grand nombre d’échecs ou de problèmes se produisent pendant le traitement de la fonction, il peut être judicieux d’arrêter la fonction, de résoudre les problèmes et de redémarrer ultérieurement.

Un point important pour les stratégies de nouvelle tentative dans Azure Functions est qu’il s’agit d’une fonctionnalité d’effort optimal pour le retraitement des événements. Cela ne remplace pas le besoin de gestion des erreurs, de journalisation et d’autres modèles importants qui assurent la résilience de votre code.

Stratégies pour les défaillances et les données endommagées

Il existe plusieurs approches intéressantes que vous pouvez utiliser pour compenser les problèmes qui surviennent en raison de défaillances ou de données incorrectes dans un flux d’événements. Voici quelques stratégies fondamentales :

  • Arrêter l’envoi et la lecture : suspendez la lecture et l’écriture des événements pour résoudre le problème sous-jacent. L’avantage de cette approche est que les données ne seront pas perdues et que les opérations pourront reprendre après le déploiement d’un correctif. Cette approche peut nécessiter un composant de disjoncteur dans l’architecture et éventuellement une notification aux services affectés pour parvenir à une pause. Dans certains cas, l’arrêt d’une fonction peut s’avérer nécessaire jusqu’à ce que les problèmes soient résolus.

  • Supprimer les messages : si les messages ne sont pas importants ou sont considérés comme critiques, envisagez de ne pas les traiter. Cette approche ne fonctionne pas pour les scénarios qui requièrent une cohérence forte, tels que l’enregistrement des déplacements dans une partie d’échecs ou des transactions financières. La gestion des erreurs à l’intérieur d’une fonction est recommandée pour l’interception et la suppression des messages qui ne peuvent pas être traités.

  • Nouvelle tentative : de nombreuses situations peuvent justifier le retraitement d’un événement. Le scénario le plus courant est une erreur temporaire rencontrée lors de l’appel d’un autre service ou dépendance. Les erreurs réseau, les limites de service et la disponibilité, ainsi que la cohérence forte sont peut-être les cas d’usage les plus fréquents qui justifient le retraitement des tentatives.

  • Lettre morte : l’idée est de publier l’événement sur un autre Event Hub afin que le flux existant ne soit pas interrompu. Il en ressort alors qu’il est écarté du chemin chaud et peut être traité ultérieurement ou par un processus différent. Cette solution est fréquemment utilisée pour gérer les messages ou les événements incohérents. Chaque fonction, qui est configurée avec un groupe de consommateurs différent, rencontrera toujours les données erronées ou endommagées dans leur flux et devra les gérer de manière responsable.

  • Nouvelle tentative et lettre morte : la combinaison de nombreuses nouvelles tentatives avant la publication finale dans un flux de lettres mortes, une fois qu’un seuil est atteint, est une autre méthode familière.

  • Utiliser un registre de schéma : un registre de schéma peut être utilisé comme outil proactif pour améliorer la cohérence et la qualité des données. Le registre de schémas Azure peut prendre en charge la transition des schémas, ainsi que le contrôle de version et différents modes de compatibilité à mesure que les schémas évoluent. À son cœur, le schéma sert de contrat entre les producteurs et les consommateurs, ce qui pourrait réduire la possibilité de publier des données non valides ou endommagées dans le flux.

En fin de compte, il n’existe pas de solution parfaite, et les conséquences et les inconvénients de chacune des stratégies doivent être examinés minutieusement. En fonction de la configuration requise, l’utilisation conjointe de plusieurs de ces techniques peut être la meilleure approche.

Contributeurs

Cet article est géré par Microsoft. Il a été écrit à l’origine par les contributeurs suivants.

Auteur principal :

Pour afficher les profils LinkedIn non publics, connectez-vous à LinkedIn.

Étapes suivantes

Avant de continuer, songez à consulter les articles connexes suivants :

Traitement d’événements sans serveur est une architecture de référence détaillant une architecture typique de ce type, avec des exemples de code et des informations importantes à prendre en compte.