Résilience et haute disponibilité dans les microservices

Conseil

Ce contenu est un extrait du livre électronique « .NET Microservices Architecture for Containerized .NET Applications », disponible sur .NET Docs ou sous forme de PDF téléchargeable gratuitement et pouvant être lu hors ligne.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

La gestion des défaillances inattendues est l’un des problèmes les plus difficiles à résoudre, en particulier dans un système distribué. Une grande partie du code que les développeurs écrivent implique la gestion des exceptions, et c’est aussi là où les tests prennent le plus de temps. Le problème est plus complexe que l’écriture de code pour gérer les défaillances. Que se passe-t-il lorsque la machine sur laquelle s’exécute le microservice échoue ? Non seulement, vous devez détecter cette défaillance du microservice (problème complexe en soi), mais des éléments sont également nécessaires au redémarrage de votre microservice.

Un microservice doit être résilient en cas de défaillance et pouvoir redémarrer souvent sur une autre machine pour assurer sa disponibilité. Cette résilience s’applique également à l’état qui a été enregistré pour le compte du microservice, où le microservice peut récupérer cet état, et si le microservice peut redémarrer correctement. En d’autres termes, il doit exister une résilience de la capacité de traitement (le processus peut redémarrer à tout moment), ainsi qu’une résilience de l’état ou des données (pas de perte de données, et les données doivent rester cohérentes).

Les problèmes de résilience peuvent être aggravés dans d’autres scénarios, comme quand des erreurs se produisent pendant la mise à niveau d’une application. Le microservice, en combinaison avec le système de déploiement, doit déterminer s’il peut continuer le processus de passage à la version plus récente ou s’il doit au contraire revenir à une version antérieure pour maintenir un état cohérent. Il faut prendre en compte les questions de savoir s’il y a suffisamment de machines disponibles pour continuer de progresser, et la manière de restaurer les versions précédentes du microservice. Cette approche implique que le microservice émette des informations sur son intégrité, afin que l’application globale et l’orchestrateur puissent prendre ces décisions.

De plus, la résilience est liée à la façon dont les systèmes basés sur le cloud doivent se comporter. Comme mentionné, un système basé sur le cloud doit traiter les défaillances et essayer de récupérer automatiquement quand elles surviennent. Par exemple, en cas de défaillances du réseau ou d’un conteneur, les applications clientes ou les services clients doivent avoir une stratégie de nouvelles tentatives d’envoi des messages ou pour les demandes, car dans de nombreux cas, les défaillances dans le cloud sont partielles. La section Implémentation d’applications résilientes de ce guide explique comment gérer une défaillance partielle. Elle décrit des techniques comme les nouvelles tentatives avec interruption exponentielle ou le modèle de disjoncteur dans .NET avec des bibliothèques comme Polly, qui offre une grande variété de stratégies pour traiter cette question.

Gestion de l’intégrité et diagnostics dans les microservices

Un microservice doit communiquer son intégrité et ses diagnostics. Cela peut sembler évident, mais ce point est souvent négligé. Sinon, peu d’informations ressortent des opérations. Corréler des événements de diagnostic sur un ensemble de services indépendants et gérer les variations d’horloges des machines afin de déterminer l’ordre des événements représente un défi. De la même façon que vous interagissez avec un microservice via des protocoles et des formats de données convenus, il est nécessaire de standardiser la journalisation de l’intégrité et des événements de diagnostic, qui sont au final stockés dans un magasin d’événements pour être interrogés et consultés. Dans une approche de microservices, il est essentiel que les différentes équipes soient d’accord sur un format de journalisation unique. Il est nécessaire d’avoir une approche cohérente pour consulter les événements de diagnostic de l’application.

Contrôles d’intégrité

L’intégrité diffère des diagnostics. L’intégrité fait référence aux rapports du microservice sur son état actuel de sorte que des actions appropriées puissent être prises. Un bon exemple de cela est l’utilisation de mécanismes de mise à niveau et de déploiement pour garantir la disponibilité. Bien qu’un service puisse être défectueux à un instant donné en raison du blocage d’un processus ou du redémarrage de l’ordinateur, le service peut néanmoins rester opérationnel. La dernière chose dont vous avez besoin est d’empirer les choses en effectuant une mise à niveau. La meilleure solution est de commencer par mener une enquête ou de laisser le temps au microservice de récupérer. Les événements d’intégrité d’un microservice nous aident à prendre des décisions avisées et nous aident effectivement à créer des services de réparation spontanée.

Dans la section Implémentation de vérifications d’intégrité dans les services ASP.NET Core de ce guide, nous expliquons comment utiliser la nouvelle bibliothèque HealthChecks d’ASP.NET dans vos microservices pour que ceux-ci puissent communiquer leur état à un service de supervision qui prendra les mesures appropriées.

Vous avez aussi la possibilité d’utiliser une excellente bibliothèque open source appelée AspNetCore.Diagnostics.HealthChecks, disponible sur GitHub et comme package NuGet. Cette bibliothèque effectue également des vérifications d’intégrité et gère étonnamment deux types de vérifications :

  • Fonctionnement : vérifie si le microservice fonctionne, c’est-à-dire s’il est capable d’accepter des demandes et d’y répondre.
  • Préparation : vérifie si les dépendances du microservice (base de données, services de file d’attente, etc.) sont elles-mêmes prêtes pour que le microservice puisse faire ce qu’il est supposé faire.

Utilisation des diagnostics et des flux d’événements des journaux

Les journaux fournissent des informations sur la façon dont une application ou un service s’exécute, notamment les exceptions, les avertissements et les simples messages d’information. En règle générale, chaque journal est au format texte, avec une ligne par événement, bien que les exceptions s’accompagnent souvent de la trace de pile sur plusieurs lignes.

Dans les applications serveur monolithiques, vous pouvez écrire les journaux dans un fichier sur disque (un fichier journal), puis les analyser avec n’importe quel outil. Comme l’exécution de l’application est limitée à un serveur ou une machine virtuelle fixe, il n’est généralement pas trop complexe d’analyser le flux des événements. Cependant, dans une application distribuée où plusieurs services sont exécutés sur de nombreux nœuds d’un cluster orchestrateur, mettre en corrélation les événements distribués peut être difficile.

Une application basée sur des microservices ne doit pas tenter de stocker elle-même le flux de sortie des événements ou des fichiers journaux, ni même tenter de gérer le routage des événements vers un emplacement central. Ce doit être transparent, ce qui signifie que chaque processus doit simplement écrire son flux d’événements vers une sortie standard, qui sera collectée plus tard par l’infrastructure de l’environnement d’exécution où il s’exécute. Microsoft.Diagnostic.EventFlow est un exemple de ces routeurs de flux d’événements, qui collecte les flux d’événements provenant de plusieurs sources et les publie sur des systèmes de sortie. Ces systèmes peuvent être des sorties standard simples pour un environnement de développement, ou des systèmes cloud comme Azure Monitor et Diagnostics Azure. Il existe également des plateformes et des outils de tiers performants pour l’analyse des journaux, qui permettent de rechercher, alerter, communiquer et surveiller les journaux, même en temps réel, comme Splunk.

Orchestrateurs gérant les informations d’intégrité et de diagnostic

Quand vous créez une application basée sur des microservices, vous devez gérer la complexité. Bien sûr, s’il est simple de traiter avec un seul microservice, le problème est bien complexe avec des dizaines ou des centaines de types de microservices, et des milliers d’instances de microservices. Il ne s’agit pas seulement de créer l’architecture de vos microservices : vous avez aussi besoin d’une haute disponibilité, d’adressabilité, de résilience, d’intégrité et de diagnostics si vous voulez avoir d’un système stable et cohésif.

Diagram of clusters supplying a support platform for microservices.

Figure 4-22. Une plateforme de microservices est essentielle pour la gestion de l’intégrité d’une application

Les problèmes complexes présentés dans la figure 4-22 sont difficiles à résoudre par vous-même. Les équipes de développement doivent se concentrer sur la résolution des problèmes métier et sur la création d’applications personnalisées avec des approches basées sur les microservices. Elles ne doivent pas se concentrer sur la résolution des problèmes d’infrastructure complexes ; si elles le font, le coût des applications basées sur des microservices serait énorme. Pour cette raison, il existe des plateformes orientée microservices, appelées orchestrateurs ou clusters de microservices, qui tentent de résoudre les difficiles problèmes de l’efficacité de la création et de l’exécution d’un service, et de l’utilisation des ressources de l’infrastructure. Cette approche réduit la complexité de la création d’applications qui utilisent une approche de microservices.

Les différents orchestrateurs peuvent sembler similaires, mais les diagnostics et les vérifications d’intégrité offerts par chacun d’eux diffèrent par leurs fonctionnalités et leur état de maturité, parfois en fonction de la plateforme du système d’exploitation, comme expliqué dans la section suivante.

Ressources supplémentaires