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.
REL05-BP01 Implémenter une dégradation progressive pour transformer les dépendances matérielles applicables en dépendances souples
Les composants de l’application doivent continuer à exécuter leur fonction principale même si les dépendances deviennent indisponibles. Ils peuvent fournir des données légèrement obsolètes, des données alternatives ou même aucune donnée. Cela garantit que le fonctionnement global du système n’est que très peu entravé par des défaillances localisées tout en fournissant une valeur commerciale centrale.
Résultat souhaité : lorsque les dépendances d’un composant ne sont pas en bon état, le composant lui-même peut continuer de fonctionner, mais de manière dégradée. Les modes de défaillance des composants doivent être considérés comme un fonctionnement normal. Les flux de travail doivent être conçus de manière à ce que ces défaillances n’aboutissent pas à une défaillance complète ou qu’elles aboutissent au moins à des états prévisibles et récupérables.
Anti-modèles courants :
-
Ne pas identifier les fonctionnalités métier essentielles nécessaires. Ne pas tester le fonctionnement des composants, même en cas de défaillance des dépendances.
-
Aucune donnée n’est diffusée en cas d’erreur ou lorsqu’une seule dépendance parmi plusieurs n’est pas disponible et que des résultats partiels peuvent toujours être renvoyés.
-
Création d’un état incohérent lorsqu’une transaction échoue partiellement.
-
Ne pas disposer d’un autre moyen d’accéder à un magasin de paramètres central.
-
Invalider ou vider l’état local à la suite d’un échec d’actualisation sans prendre en compte les conséquences d’une telle opération.
Avantages du respect de cette bonne pratique : une dégradation progressive améliore la disponibilité du système dans son ensemble et maintient la fonctionnalité des fonctions les plus importantes même en cas de panne.
Niveau d’exposition au risque si cette bonne pratique n’est pas respectée : élevé
Directives d’implémentation
La mise en œuvre d’une dégradation progressive permet de minimiser l’impact des défaillances de dépendance sur le fonctionnement des composants. Idéalement, un composant détecte les défaillances liées aux dépendances et les contourne de manière à avoir un impact minimal sur les autres composants ou les clients.
L’architecture permettant une dégradation progressive implique de prendre en compte les modes de défaillance potentiels lors de la conception des dépendances. Pour chaque mode de défaillance, déterminez un moyen de fournir la plupart des fonctionnalités, ou les plus critiques d’entre elles, du composant aux appelants ou aux clients. Ces considérations peuvent devenir des exigences supplémentaires qui peuvent être testées et vérifiées. Idéalement, un composant est capable d’exécuter sa fonction principale de manière acceptable, même en cas de défaillance d’une ou de plusieurs dépendances.
Il s’agit tout autant d’une discussion commerciale que technique. Toutes les exigences commerciales sont importantes et doivent être satisfaites dans la mesure du possible. Cependant, il est tout de même logique de se demander ce qui doit se passer lorsque toutes les exigences ne peuvent pas être satisfaites. Un système peut être conçu pour être disponible et cohérent, mais lorsqu’une exigence doit être supprimée, laquelle est la plus importante ? Pour le traitement des paiements, il peut s’agir de la cohérence. Pour une application en temps réel, il peut s’agir de la disponibilité. Pour un site Web orienté client, la réponse peut dépendre des attentes du client.
Ce que cela signifie dépend des exigences du composant et de ce qui doit être considéré comme sa fonction principale. Par exemple :
-
un site Web d’e-commerce peut afficher des données provenant de plusieurs systèmes différents, par exemple des recommandations personnalisées, les produits les mieux classés et l’état des commandes des clients sur la page de destination. Lorsqu’un système en amont est défaillant, il est tout de même judicieux d’afficher tout le reste au lieu d’afficher une page d’erreur à un client.
-
Un composant effectuant des écritures par lots peut toujours continuer à traiter un lot si l’une des opérations individuelles échoue. La mise en œuvre d’un mécanisme de nouvelle tentative doit être simple. Cela peut être fait en renvoyant à l’appelant des informations indiquant quelles opérations ont réussi, lesquelles ont échoué et pourquoi elles ont échoué, ou en plaçant les demandes ayant échoué dans une file d’attente de lettres mortes pour implémenter des tentatives asynchrones. Les informations relatives aux opérations ayant échoué doivent également être consignées.
-
Un système qui traite les transactions doit vérifier que toutes les mises à jour individuelles sont exécutées ou qu’aucune d’entre elles ne l’est. Pour les transactions distribuées, le modèle Saga peut être utilisé pour annuler les opérations précédentes en cas d’échec d’une opération ultérieure de la même transaction. Ici, la fonction principale est de maintenir la cohérence.
-
Les systèmes soumis à des contraintes de temps doivent être en mesure de gérer les dépendances qui ne répondent pas en temps voulu. Dans ces cas de figure, le modèle du disjoncteur peut être utilisé. Lorsque les réponses d’une dépendance commencent à expirer, le système peut passer à un état fermé où aucun appel supplémentaire n’est effectué.
-
Une application peut lire des paramètres à partir d’un magasin de paramètres. Il peut être utile de créer des images de conteneur avec un ensemble de paramètres par défaut et de les utiliser si le magasin de paramètres n’est pas disponible.
Notez que les chemins empruntés en cas de défaillance d’un composant doivent être testés et doivent être nettement plus simples que le chemin principal. Généralement, les stratégies de repli doivent être évitées
Étapes d’implémentation
Identifiez les dépendances externes et internes. Déterminez quels types de défaillances peuvent y survenir. Réfléchissez à des moyens de minimiser l’impact négatif sur les systèmes en amont et en aval, ainsi que sur les clients lors de ces défaillances.
Vous trouverez ci-dessous une liste des dépendances et la manière de les dégrader de façon appropriée en cas d’échec :
-
Défaillance partielle des dépendances : un composant peut adresser plusieurs demandes à des systèmes en aval, soit sous la forme de demandes multiples adressées à un système, soit sous celle d’une demande adressée à plusieurs systèmes. Selon le contexte métier, différentes méthodes de gestion peuvent être appropriées (pour plus de détails, voir les exemples précédents dans le guide de mise en œuvre).
-
Un système en aval est incapable de traiter les demandes en raison d’une charge élevée : si les demandes adressées à un système en aval échouent régulièrement, il n’est pas logique de continuer à réessayer. Cela peut créer une charge supplémentaire sur un système déjà surchargé et rendre la récupération plus difficile. Le modèle du disjoncteur peut être utilisé ici afin de surveiller les appels en échec vers un système en aval. Si un grand nombre d’appels échouent, il cessera d’envoyer d’autres demandes au système en aval et n’autorisera les appels qu’occasionnellement pour vérifier si le système en aval est à nouveau disponible.
-
Aucun magasin de paramètres n’est disponible : pour transformer un magasin de paramètres, vous pouvez utiliser la mise en cache des dépendances souples ou des valeurs par défaut saines incluses dans les images de conteneur ou de machine. Notez que ces valeurs par défaut doivent être conservées up-to-date et incluses dans les suites de tests.
-
Aucun service de surveillance ou autre dépendance non fonctionnelle n’est disponible : si un composant ne peut pas envoyer par intermittence des journaux, des métriques ou des traces à un service de surveillance central, il est souvent préférable de continuer à exécuter les fonctions métier comme d’habitude. Il est souvent inacceptable de ne pas enregistrer ni de pousser des métriques pendant une longue période. En outre, certains cas d’utilisation peuvent nécessiter des entrées d’audit complètes pour répondre aux exigences de conformité.
-
Il est possible qu’une instance principale d’une base de données relationnelle ne soit pas disponible : Amazon Relational Database Service, comme presque toutes les bases de données relationnelles, ne peut avoir qu’une seule instance de rédacteur principal. Cela crée un point de défaillance unique pour les charges de travail d’écriture et complique la mise à l’échelle. Ce problème peut être partiellement atténué en utilisant une configuration multi-AZ pour une haute disponibilité ou Amazon Aurora sans serveur pour une meilleure mise à l’échelle. Pour des exigences de très haute disponibilité, il peut être judicieux de ne pas se fier du tout au rédacteur principal. Pour les requêtes qui se limitent à la lecture, des répliques de lecture peuvent être utilisées, ce qui assure la redondance et la possibilité d’une augmentation horizontale, et pas seulement d’une augmentation verticale. Les écritures peuvent être mises en mémoire tampon, par exemple dans une file d’attente Amazon Simple Queue Service, afin que les demandes d’écriture des clients puissent toujours être acceptées même si le serveur principal est temporairement indisponible.
Ressources
Documents connexes :
-
Amazon API Gateway : limitez les API demandes pour un meilleur débit
-
CircuitBreaker(résume le disjoncteur de « Release It ! » livre)
-
Michael Nygard « Release It! Design and Deploy Production-Ready Software »
-
L’Amazon Builders’ Library : éviter le basculement dans les systèmes distribués
-
L’Amazon Builders’ Library : éviter les retards de file d’attente insurmontables
-
L’Amazon Builders’ Library : défis et stratégies de mise en cache
-
Amazon Builders’ Library : délais d’attente, nouvelles tentatives et backoff avec instabilité
Vidéos connexes :
Exemples connexes :