Modifier

Partager via


Modèle Disjoncteur

Azure

Gérer les erreurs pour lesquelles la récupération peut prendre un certain temps lors de la connexion à une ressource ou à un service distant. Ce modèle peut améliorer la stabilité et la résilience d’une application.

Contexte et problème

Dans un environnement distribué, les appels aux ressources et services distants peuvent échouer en raison d’erreurs temporaires, telles que les connexions réseau lentes, les délais d’attente ou les ressources en cours de surajustement ou temporairement indisponibles. Ces erreurs disparaissent en général automatiquement après un court laps de temps, et une application cloud fiable doit être prête à les gérer à l’aide d’une stratégie telle que le modèle Nouvelle tentative.

Toutefois, dans certaines situations les erreurs sont dues à des événements imprévus et peuvent durer beaucoup plus longtemps. Ces erreurs peuvent aller d’une perte partielle de connectivité à la défaillance complète d’un service. Dans ces situations, il peut être inutile qu’une application recommencez continuellement une opération qui est peu susceptible de réussir, et au lieu de cela, l’application doit accepter rapidement que l’opération a échoué et gérer cette défaillance en conséquence.

De plus, si un service est très occupé, un échec dans une partie du système peut entraîner des défaillances en cascade. Par exemple, une opération qui appelle un service peut être configurée pour implémenter un délai d’attente et répondre avec un message d’échec si le service ne répond pas pendant cette période. Toutefois, cette stratégie peut entraîner le blocage de nombreuses requêtes simultanées vers la même opération jusqu’à l’expiration du délai d’expiration. Ces demandes bloquées peuvent contenir des ressources système critiques telles que de la mémoire, des threads, des connexions de base de données, et ainsi de suite. Par conséquent, ces ressources peuvent devenir épuisées, provoquant une défaillance d’autres parties potentiellement non liées du système qui doivent utiliser les mêmes ressources. Dans ces situations, il serait préférable que l’opération échoue immédiatement et que l’appel du service soit tenté uniquement s’il est susceptible de réussir. La définition d’un délai d’attente plus court peut aider à résoudre ce problème, mais le délai d’attente ne doit pas être si court que l’opération échoue la plupart du temps, même si la demande adressée au service aboutit.

Solution

Le modèle Disjoncteur peut empêcher une application d’essayer à plusieurs reprises d’exécuter une opération susceptible d’échouer. Cela lui permet de continuer sans attendre que l’erreur soit corrigée ou sans gaspiller des cycles de processeur pendant qu’elle détermine qu’il s’agit d’une erreur de longue durée. Le modèle Disjoncteur permet également à une application de détecter si l’erreur a été corrigée. Si le problème semble avoir été résolu, l’application peut essayer d’appeler l’opération.

L’objectif du modèle Disjoncteur est différent de celui du modèle Nouvelle tentative. Le modèle Nouvelle tentative permet à une application de retenter une opération en partant du principe qu’elle finira par réussir. Le modèle Disjoncteur empêche une application d’effectuer une opération qui échouera probablement. Une application peut combiner ces deux modèles en utilisant le modèle Nouvelle tentative pour appeler une opération par le biais d’un disjoncteur. Toutefois, la logique de nouvelle tentative doit être sensible aux exceptions retournées par le disjoncteur, et abandonner les nouvelles tentatives si le disjoncteur indique qu’une erreur n’est pas temporaire.

Un disjoncteur agit comme un proxy pour les opérations qui risquent d’échouer. Le proxy doit surveiller le nombre de défaillances récentes qui se sont produites et utiliser ces informations pour décider s’il faut autoriser l’opération à continuer ou retourner immédiatement une exception.

Le proxy peut être implémenté en tant que machine d’état avec les états suivants qui simulent la fonctionnalité d’un disjoncteur électrique :

  • Fermé : La requête de l’application est routée vers l’opération. Le proxy tient à jour un décompte du nombre d’échecs récents, et si l’appel à l’opération n’aboutit pas, le proxy incrémente ce nombre. Si le nombre d’échecs récents dépasse un seuil spécifié pendant une période donnée, le proxy est placé à l’état Ouvert. À ce stade, le proxy démarre un minuteur de délai d’attente, et lorsque ce minuteur expire, le proxy est placé dans l’état demi-ouverture.

    L’objectif du minuteur de délai d’attente est de donner au système le temps nécessaire pour résoudre le problème qui a provoqué l’échec avant d’autoriser l’application à réessayer d’effectuer l’opération.

  • Ouvrir : La requête de l’application est immédiatement un échec. Une exception est retournée à l’application.

  • Demi-ouvert : Un nombre limité de requêtes provenant de l’application est autorisé à passer et à appeler l’opération. Si ces demandes réussissent, on considère que l’erreur ayant provoqué l’échec a été corrigée et le disjoncteur passe à l’état Fermé (le compteur d’échecs est réinitialisé). Si une demande échoue, le disjoncteur suppose que l’erreur est toujours présente afin qu’elle revient à l’état Ouvrir et redémarre le minuteur de délai d’attente pour donner au système une période supplémentaire de récupération à partir de l’échec.

    L’état Demi-ouvert est utile pour empêcher qu’un service en train de récupérer ne soit submergé soudainement de demandes. Quand un service est en cours de récupération, il peut être capable de prendre en charge un volume limité de demandes jusqu’à ce que la récupération soit terminée, mais pendant que la récupération est en cours un flux de travail peut provoquer un nouvel échec ou l’expiration du délai de service.

États du disjoncteur

Dans la figure, le compteur d’échecs utilisé par l’état Fermé est temporel. Il est réinitialisé automatiquement à intervalles réguliers. Cette conception permet d’empêcher le disjoncteur d’entrer dans l’état Ouvrir s’il rencontre des défaillances occasionnelles. Le seuil d’échec qui fait basculer le disjoncteur à l’état Ouvert est atteint uniquement quand un nombre spécifié d’échecs se sont produits pendant un intervalle spécifié. Le compteur utilisé par l’état Demi-ouvert enregistre le nombre de tentatives d’appel de l’opération qui ont réussi. Le disjoncteur repasse à l’état Fermé une fois qu’un nombre spécifié d’appels d’opérations consécutifs ont abouti. Si un appel échoue, le disjoncteur bascule immédiatement à l’état Ouvert et le compteur de réussites est réinitialisé la prochaine fois qu’il bascule à l’état Demi-ouvert.

Le mode de récupération du système est géré en externe, éventuellement par la restauration ou le redémarrage d’un composant défectueux ou la réparation d’une connexion réseau.

Le modèle Disjoncteur assure la stabilité pendant que le système récupère après un échec, et il réduit l’impact sur les performances. Il peut aider à maintenir le temps de réponse du système en rejetant rapidement une demande pour une opération qui échouera probablement, plutôt que d’attendre que l’opération expire ou ne retourne jamais. Si le disjoncteur déclenche un événement chaque fois qu’il change d’état, cette information peut être utilisée pour surveiller l’intégrité de la partie du système protégée par le disjoncteur, ou pour alerter l’administrateur quand un disjoncteur bascule à l’état Ouvert.

Le modèle est personnalisable et peut être adapté en fonction du type de défaillance possible. Par exemple, vous pouvez appliquer un minuteur de délai d’attente croissant à un disjoncteur. Vous pouvez placer le disjoncteur dans l’état Ouvrir pendant quelques secondes au départ, puis si l’échec n’a pas été résolu, augmentez le délai d’attente à quelques minutes, et ainsi de suite. Dans certains cas, plutôt que de faire en sorte que l’état Ouvert retourne un échec et déclenche une exception, il peut être utile de retourner une valeur par défaut qui est significative pour l’application.

Notes

Traditionnellement, les disjoncteurs s’appuient sur des seuils préconfigurés tels que le nombre d’échecs et la durée d’expiration, ce qui entraîne un comportement déterministe mais parfois non optimal. Toutefois, les techniques adaptatives utilisant l’IA et ML peuvent ajuster dynamiquement les seuils en fonction des modèles de trafic en temps réel, des anomalies et des taux d’échec historique, ce qui rend le disjoncteur plus résilient et plus efficace.

Problèmes et considérations

Prenez en compte les points suivants quand vous choisissez comment implémenter ce modèle :

gestion des exceptions: une application appelant une opération par le biais d’un disjoncteur doit être prête à gérer les exceptions déclenchées si l’opération n’est pas disponible. Le traitement des exceptions est propre à l’application. Par exemple, une application peut temporairement dégrader ses fonctionnalités, appeler une opération de remplacement pour tenter d’effectuer la même tâche ou obtenir les mêmes données, ou signaler l’exception à l’utilisateur et lui demander de réessayer ultérieurement.

Types d’exceptions: une requête peut échouer pour de nombreuses raisons, dont certaines peuvent indiquer un type de défaillance plus grave que d’autres. Par exemple, une demande peut échouer, car un service distant s’est arrêté et prend plusieurs minutes pour récupérer, ou en raison d’un délai d’attente en raison d’un surcharge temporaire du service. Un disjoncteur peut être en mesure d’examiner les types d’exceptions qui se produisent et d’ajuster sa stratégie d’après la nature de ces exceptions. Par exemple, il peut nécessiter un plus grand nombre d’exceptions de délai d’attente pour faire passer le disjoncteur au 'état Open par rapport au nombre d’échecs en raison du service complètement indisponible.

Surveillance: un disjoncteur doit fournir une observabilité claire dans les demandes ayant échoué et réussies, ce qui permet aux équipes d’opérations d’évaluer l’intégrité du système. Utilisez le suivi distribué pour une visibilité de bout en bout entre les services.

de récupération : vous devez configurer le disjoncteur pour qu’il corresponde au modèle de récupération probable de l’opération qu’il protège. Par exemple, si le disjoncteur reste à l’état Ouvert pendant une longue période, il peut lever des exceptions même si la cause de l’échec a disparu. De même, un disjoncteur peut fluctuer et réduire le temps de réponse des applications s’il bascule trop rapidement de l’état Ouvert à l’état Demi-ouvert.

Test des opérations ayant échoué: dans l’état Ouvrir, plutôt que d’utiliser un minuteur pour déterminer quand basculer vers l’état demi-ouverture, un disjoncteur peut effectuer régulièrement un test ping sur le service distant ou la ressource pour déterminer s’il est de nouveau disponible. Cette commande ping peut prendre la forme d’une tentative d’appel d’une opération qui a précédemment échoué. Vous pourriez aussi utiliser une opération spéciale fournie par le service distant spécifiquement pour tester l’intégrité du service, comme indiqué par le Modèle de surveillance de point de terminaison d’intégrité.

remplacement manuel: dans un système où le temps de récupération d’une opération défaillante est extrêmement variable, il est utile de fournir une option de réinitialisation manuelle qui permet à un administrateur de fermer un disjoncteur (et de réinitialiser le compteur d’échec). De même, un administrateur peut forcer un disjoncteur dans l’état Ouvrir (et redémarrer le minuteur de délai d’attente) si l’opération protégée par le disjoncteur est temporairement indisponible.

accès concurrentiel: le même disjoncteur est accessible par un grand nombre d’instances simultanées d’une application. L’implémentation ne doit pas bloquer les demandes simultanées, ni ajouter une surcharge excessive à chaque appel à une opération.

différenciation des ressources: soyez prudent lors de l’utilisation d’un disjoncteur unique pour un type de ressource s’il peut y avoir plusieurs fournisseurs indépendants sous-jacents. Par exemple, dans un magasin de données qui contient plusieurs partitions, l’une d’entre elles peut être entièrement accessible alors qu’une autre rencontre un problème temporaire. Si les réponses aux erreurs dans ces scénarios sont fusionnées, une application risque de tenter d’accéder à certaines partitions même quand l’échec est très probable, tandis que l’accès à d’autres partitions risque d’être bloqué alors qu’il a toutes les chances de réussir.

interruption de circuit accélérée: parfois, une réponse d’échec peut contenir suffisamment d’informations pour que le disjoncteur voyage immédiatement et restez trippé pendant une durée minimale. Par exemple, la réponse d’erreur d’une ressource partagée qui est surchargée peut indiquer qu’une nouvelle tentative immédiate n’est pas recommandée, et que l’application doit plutôt réessayer dans quelques minutes.

déploiements multirégions: un disjoncteur peut être conçu pour des déploiements à une ou plusieurs régions. Cette dernière peut être implémentée à l’aide d’équilibreurs de charge globaux ou de stratégies de rupture de circuit personnalisées prenant en charge les régions, qui garantissent un basculement contrôlé, l’optimisation de la latence et la conformité réglementaire.

disjoncteurs de maillage de service: les disjoncteurs peuvent être implémentés au niveau de la couche application ou en tant que caractéristique croisée et abstraite. Par exemple, les maillages de service prennent souvent en charge la rupture de circuit en tant que side-car ou en tant que fonctionnalité autonome sans modifier le code de l’application.

Notes

Un service peut retourner HTTP 429 (Trop de requêtes) s’il limite le client ou HTTP 503 (Service indisponible) si le service n’est pas disponible actuellement. La réponse peut inclure des informations supplémentaires, telles que la durée prévue du retard.

les demandes ayant échoué: dans l’état Ouvrir, au lieu d’échouer rapidement, un disjoncteur peut également enregistrer les détails de chaque requête dans un journal et organiser la relecture de ces demandes lorsque la ressource ou le service distant devient disponible.

délais d’attente inappropriés sur les services externes: un disjoncteur peut ne pas être en mesure de protéger entièrement les applications contre les opérations qui échouent dans les services externes configurés avec un délai d’attente long. Si le délai d’attente est trop long, un thread exécutant un disjoncteur peut être bloqué pendant une période prolongée avant que le disjoncteur indique que l’opération a échoué. Pendant ce temps, de nombreuses autres instances peuvent également tenter d’appeler le service par le biais du disjoncteur, et occuper un nombre important de threads avant que toutes n’échouent.

Adaptabilité pour la diversification du calcul: les disjoncteurs doivent tenir compte de différents environnements de calcul, de serverless à des charges de travail conteneurisées, où des facteurs tels que les démarrages à froid et la gestion des défaillances d’impact sur l’évolutivité. Les approches adaptatives peuvent ajuster dynamiquement des stratégies basées sur le type de calcul, ce qui garantit la résilience entre les architectures hétérogènes.

Quand utiliser ce modèle

Utilisez ce modèle :

  • Pour éviter les défaillances en cascade en arrêtant des appels excessifs par un service distant ou des demandes d’accès à une ressource partagée si ces opérations sont très susceptibles d’échouer.
  • Pour améliorer la résilience multirégion en acheminant le trafic intelligemment en fonction des signaux d’échec en temps réel.
  • Pour vous protéger contre les dépendances lentes, vous aider à suivre vos objectifs de niveau de service (SLA) et à éviter la dégradation des performances en raison de services à latence élevée.
  • Pour gérer les problèmes de connectivité intermittents et réduire les échecs de requête dans les environnements distribués.

Ce modèle n’est pas recommandé :

  • Pour la gestion de l’accès aux ressources privées locales dans une application, comme la structure de données en mémoire. Dans cet environnement, l’utilisation d’un disjoncteur ajouterait une surcharge à votre système.
  • Comme substitut pour la gestion des exceptions dans la logique métier de vos applications.
  • Lorsque les algorithmes de nouvelle tentative connus sont suffisants et que vos dépendances sont conçues pour gérer les mécanismes de nouvelle tentative. L’implémentation d’un disjoncteur dans votre application dans ce cas peut ajouter une complexité inutile à votre système.
  • Lorsque vous attendez qu’un disjoncteur soit réinitialisé, cela peut entraîner des retards inacceptables.
  • Si vous avez une architecture pilotée par des messages ou pilotée par des événements, car elles routent souvent les messages ayant échoué vers une file d’attente de lettres mortes (DLQ) pour le traitement manuel ou différé. L’isolation des défaillances intégrées et les mécanismes de nouvelle tentative généralement implémentés dans ces conceptions sont souvent suffisants.
  • Si la récupération d’échec est gérée au niveau de l’infrastructure ou de la plateforme, par exemple avec des contrôles d’intégrité dans des équilibreurs de charge globaux ou des maillages de service, les disjoncteurs peuvent ne pas être nécessaires.

Conception de la charge de travail

Un architecte doit évaluer la façon dont le modèle Disjoncteur peut être utilisé dans la conception de leurs charges de travail pour se conformer aux objectifs et principes abordés dans les piliers d’Azure Well-Architected Framework. Par exemple :

Pilier Comment ce modèle soutient les objectifs des piliers.
Les décisions relatives à la fiabilité contribuent à rendre votre charge de travail résiliente aux dysfonctionnements et à s’assurer qu’elle retrouve un état de fonctionnement optimal après une défaillance. Ce modèle empêche la surcharge d’une dépendance défaillante. Vous pouvez également l’utiliser pour déclencher une dégradation progressive dans la charge de travail. Les disjoncteurs sont souvent couplés à la récupération automatique pour assurer à la fois l’auto-conservation et la réparation spontanée.

- RE :03 Analyse du mode d’échec
- RE :07 Erreurs temporaires
- RE :07 Auto-conservation
L’efficacité des performances permet à votre charge de travail de répondre efficacement aux demandes grâce à des optimisations de la mise à l’échelle, des données, du code. Ce modèle permet d’éviter l’approche nouvelle tentative en cas d’erreur, qui peut entraîner une utilisation excessive des ressources lors de la récupération des dépendances et peut également surcharger les performances d’une dépendance qui tente une récupération.

- PE :07 Code et infrastructure
- PE :11 Réponses aux problèmes en direct

Comme pour toute autre décision de conception, il convient de prendre en compte les compromis par rapport aux objectifs des autres piliers qui pourraient être introduits avec ce modèle.

Les modèles suivants peuvent également être utiles lors de l’implémentation de ce modèle :

  • Le modèle d’application web fiable vous montre comment appliquer le modèle disjoncteur aux applications web convergeant vers le cloud.

  • Modèle Nouvelle tentative. Décrit comment une application peut gérer les défaillances temporaires anticipées quand elle tente de se connecter à un service ou à une ressource réseau en réessayant d’exécuter en toute transparence une opération qui a échoué précédemment.

  • Modèle Supervision de point de terminaison d’intégrité. Un disjoncteur peut tester l’intégrité d’un service en envoyant une demande à un point de terminaison exposé par le service. Le service doit retourner des informations indiquant son état.