Schéma du disjoncteur - AWS Conseils prescriptifs

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Schéma du disjoncteur

Intention

Le schéma du disjoncteur peut empêcher un service appelant de retenter un appel vers un autre service (appelé) lorsque l'appel a déjà provoqué des délais ou des échecs répétés. Le modèle est également utilisé pour détecter le moment où le service appelé est à nouveau fonctionnel.

Motivation

Lorsque plusieurs microservices collaborent pour traiter les demandes, un ou plusieurs services peuvent devenir indisponibles ou présenter une latence élevée. Lorsque des applications complexes utilisent des microservices, une panne d'un microservice peut entraîner la défaillance de l'application. Les microservices communiquent par le biais d'appels de procédure à distance, et des erreurs transitoires peuvent survenir dans la connectivité réseau et provoquer des défaillances. (Les erreurs transitoires peuvent être gérées en utilisant le modèle de nouvelle tentative avec retrait.) Lors d'une exécution synchrone, la cascade de délais ou d'échecs peut nuire à l'expérience utilisateur.

Cependant, dans certains cas, la résolution des défaillances peut prendre plus de temps, par exemple lorsque le service appelé est en panne ou qu'un conflit de base de données entraîne des délais d'attente. Dans de tels cas, si le service d'appel tente les appels à plusieurs reprises, ces tentatives peuvent entraîner un conflit sur le réseau et une consommation du pool de threads de base de données. En outre, si plusieurs utilisateurs réessayent l'application à plusieurs reprises, cela ne fera qu'aggraver le problème et entraîner une dégradation des performances de l'ensemble de l'application.

Le schéma du disjoncteur a été popularisé par Michael Nygard dans son livre, Release It (Nygard 2018). Ce modèle de conception peut empêcher un service appelant de réessayer un appel de service qui a déjà provoqué des délais ou des échecs répétés. Il peut également détecter le moment où le service appelé est à nouveau fonctionnel.

Les objets disjoncteurs fonctionnent comme des disjoncteurs électriques qui interrompent automatiquement le courant en cas d'anomalie dans le circuit. Les disjoncteurs électriques coupent ou déclenchent la circulation du courant en cas de panne. De même, l'objet disjoncteur est situé entre l'appelant et le service appelé, et se déclenche si l'appelé n'est pas disponible.

Les erreurs de l'informatique distribuée sont un ensemble d'assertions faites par Peter Deutsch et d'autres collaborateurs de Sun Microsystems. Ils disent que les programmeurs novices dans le domaine des applications distribuées font invariablement de fausses suppositions. La fiabilité du réseau, les attentes en matière de latence nulle et les limites de bande passante se traduisent par des applications logicielles conçues avec une gestion minimale des erreurs réseau.

Lors d'une panne réseau, les applications peuvent attendre indéfiniment une réponse et consommer continuellement leurs ressources. Le fait de ne pas recommencer les opérations lorsque le réseau devient disponible peut également entraîner une dégradation des applications. Si API les appels à une base de données ou à un service externe sont interrompus en raison de problèmes de réseau, des appels répétés sans disjoncteur peuvent affecter les coûts et les performances.

Applicabilité

Utilisez ce modèle lorsque :

  • Le service d'appel passe un appel qui risque fort d'échouer.

  • Une latence élevée du service appelé (par exemple, lorsque les connexions à la base de données sont lentes) entraîne des délais d'attente pour le service appelé.

  • Le service d'appel effectue un appel synchrone, mais le service appelé n'est pas disponible ou présente une latence élevée.

Problèmes et considérations

  • Implémentation indépendante du service : pour éviter toute surcharge de code, nous vous recommandons d'implémenter l'objet disjoncteur d'une manière indépendante et pilotée par les microservices. API

  • Fermeture du circuit par l'appelé : lorsque l'appelé se remet d'un problème ou d'une panne de performance, il peut mettre à jour l'état du circuit sur. CLOSED Il s'agit d'une extension du schéma du disjoncteur qui peut être mise en œuvre si votre objectif de temps de rétablissement (RTO) l'exige.

  • Appels multithread : la valeur du délai d'expiration est définie comme la période pendant laquelle le circuit reste déclenché avant que les appels ne soient à nouveau routés pour vérifier la disponibilité du service. Lorsque le service appelé est appelé dans plusieurs threads, le premier appel qui a échoué définit la valeur du délai d'expiration. Votre implémentation doit garantir que les appels suivants ne déplacent pas le délai d'expiration indéfiniment.

  • Forcer l'ouverture ou la fermeture du circuit : les administrateurs système doivent avoir la possibilité d'ouvrir ou de fermer un circuit. Cela peut être fait en mettant à jour la valeur du délai d'expiration dans la table de base de données.

  • Observabilité : L'application doit avoir une journalisation configurée pour identifier les appels qui échouent lorsque le disjoncteur est ouvert.

Mise en œuvre

Architecture de haut niveau

Dans l'exemple suivant, l'appelant est le service de commande et l'appelé est le service de paiement.

Lorsqu'il n'y a pas de panne, le service de commande achemine tous les appels vers le service de paiement par le disjoncteur, comme le montre le schéma suivant.

Schéma de disjoncteur sans défaillance.

Si le délai d'expiration du service de paiement est dépassé, le disjoncteur peut détecter le délai d'expiration et suivre la panne.

Disjoncteur avec défaillance du service de paiement.

Si les délais d'attente dépassent un seuil spécifié, l'application ouvre le circuit. Lorsque le circuit est ouvert, l'objet du disjoncteur n'achemine pas les appels vers le service de paiement. Il renvoie une panne immédiate lorsque le service de commande appelle le service de paiement.

Le disjoncteur arrête le routage vers le service de paiement.

L'objet disjoncteur essaie périodiquement de voir si les appels au service de paiement aboutissent.

Le disjoncteur réessaie périodiquement le service de paiement.

Lorsque l'appel au service de paiement aboutit, le circuit est fermé et tous les autres appels sont à nouveau acheminés vers le service de paiement.

Disjoncteur avec service de paiement fonctionnel.

Mise en œuvre au moyen AWS de services

L'exemple de solution utilise des flux de travail express AWS Step Functionspour implémenter le schéma du disjoncteur. La machine d'état Step Functions vous permet de configurer les capacités de nouvelle tentative et le flux de contrôle basé sur les décisions nécessaires à la mise en œuvre du modèle.

La solution utilise également une table Amazon DynamoDB comme magasin de données pour suivre l'état du circuit. Cela peut être remplacé par une banque de données en mémoire telle qu'Amazon ElastiCache (RedisOSS) pour de meilleures performances.

Lorsqu'un service souhaite appeler un autre service, il lance le flux de travail avec le nom du service appelé. Le flux de travail obtient l'état du disjoncteur à partir de la table CircuitStatus DynamoDB, qui stocke les services actuellement dégradés. S'il CircuitStatus contient un dossier non expiré pour l'appelé, le circuit est ouvert. Le flux de travail Step Functions renvoie une défaillance immédiate et s'en sort avec un FAIL état.

Si la CircuitStatus table ne contient aucun enregistrement pour l'appelé ou contient un enregistrement expiré, le service est opérationnel. L'ExecuteLambdaétape de définition de la machine à états appelle la fonction Lambda qui est envoyée via une valeur de paramètre. Si l'appel aboutit, le flux de travail Step Functions se termine avec un SUCCESS état.

Implémentation de disjoncteurs avec DynamoDB AWS Step Functions et DynamoDB.

En cas d'échec de l'appel de service ou d'expiration du délai imparti, l'application réessaie avec un retard exponentiel pendant un nombre défini de fois. Si l'appel de service échoue après les nouvelles tentatives, le flux de travail insère un enregistrement dans le CircuitStatus tableau pour le service avec un anExpiryTimeStamp, et le flux de travail sort avec un FAIL état. Les appels ultérieurs au même service entraînent une panne immédiate tant que le disjoncteur est ouvert. L'Get Circuit Statusétape de définition de la machine à états vérifie la disponibilité du service en fonction de la ExpiryTimeStamp valeur. Les éléments expirés sont supprimés de la CircuitStatus table à l'aide de la fonctionnalité DynamoDB time to live TTL ().

Exemple de code

Le code suivant utilise la fonction GetCircuitStatus Lambda pour vérifier l'état du disjoncteur.

var serviceDetails = _dbContext.QueryAsync<CircuitBreaker>(serviceName, QueryOperator.GreaterThan, new List<object> {currentTimeStamp}).GetRemainingAsync(); if (serviceDetails.Result.Count > 0) { functionData.CircuitStatus = serviceDetails.Result[0].CircuitStatus; } else { functionData.CircuitStatus = ""; }

Le code suivant montre les instructions Amazon States Language dans le flux de travail Step Functions.

"Is Circuit Closed": { "Type": "Choice", "Choices": [ { "Variable": "$.CircuitStatus", "StringEquals": "OPEN", "Next": "Circuit Open" }, { "Variable": "$.CircuitStatus", "StringEquals": "", "Next": "Execute Lambda" } ] }, "Circuit Open": { "Type": "Fail" }

GitHub référentiel

Pour une implémentation complète de l'exemple d'architecture pour ce modèle, consultez le GitHub référentiel à l'adresse https://github.com/aws-samples/circuit-breaker-netcore-blog.

Références du blog

Contenu connexe