Résilience et haute disponibilité dans les microservices

Conseil / Astuce

Ce contenu est un extrait du livre électronique 'Architecture des microservices .NET pour les applications .NET conteneurisées', disponible sur .NET Docs ou en tant que PDF téléchargeable gratuitement, lisible hors ligne.

Architecture de microservices .NET pour les applications .NET conteneurisées - vignette de couverture du livre électronique.

La gestion des défaillances inattendues est l’un des problèmes les plus difficiles à résoudre, en particulier dans un système distribué. La plupart du code que les développeurs écrivent impliquent la gestion des exceptions, et c’est également là que le plus de temps est passé dans les tests. Le problème est plus impliqué que l’écriture de code pour gérer les défaillances. Que se passe-t-il lorsque l’ordinateur sur lequel le microservice s’exécute échoue ? Non seulement avez-vous besoin de détecter cette défaillance de microservice (un problème difficile par lui-même), mais vous avez également besoin d’un élément pour redémarrer votre microservice.

Un microservice doit être résilient aux défaillances et être en mesure de redémarrer souvent sur un autre ordinateur pour la disponibilité. Cette résilience revient é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 y avoir une résilience dans la capacité de calcul (le processus peut redémarrer à tout moment) ainsi que la résilience dans l’état ou les données (aucune perte de données et les données restent cohérentes).

Les problèmes de résilience sont exacerbés pendant d'autres scénarios, comme lorsque des défaillances se produisent lors de la mise à niveau d'une application. Le microservice, qui fonctionne avec le système de déploiement, doit déterminer s’il peut continuer à passer à la version plus récente ou à restaurer une version précédente pour maintenir un état cohérent. Des questions telles que la disponibilité de suffisamment de machines pour continuer à avancer et la façon de récupérer les versions précédentes du microservice doivent être prises en compte. Cette approche nécessite que le microservice émette des informations de santé afin que l’application d'ensemble et l’orchestrateur puissent prendre ces décisions.

En outre, la résilience est liée à la façon dont les systèmes cloud doivent se comporter. Comme indiqué, un système basé sur le cloud doit prendre en compte les défaillances et tenter de s'en rétablir automatiquement. Par exemple, en cas d’échecs de réseau ou de conteneur, les applications clientes ou les services clients doivent avoir une stratégie pour réessayer l’envoi de messages ou de nouvelles demandes, car dans de nombreux cas, les défaillances dans le cloud sont partielles. La section Implémentation d’applications résilientes dans ce guide explique comment gérer les défaillances partielles. Il décrit des techniques telles que les tentatives de nouvelle exécution avec un backoff exponentiel ou le modèle Disjoncteur dans .NET, à l'aide de bibliothèques comme Polly, qui offre une grande variété de stratégies pour gérer ce sujet.

Gestion de la santé et diagnostics au sein des microservices

Il peut sembler évident, mais cela est souvent négligé, un microservice doit signaler son état de santé et ses diagnostics. Sinon, il y a peu d'aperçu dans une perspective opérationnelle. La corrélation des événements de diagnostic sur un ensemble de services indépendants et la gestion des décalages de l'horloge des machines pour donner un sens à l'ordre des événements est difficile. 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 normaliser la façon de consigner les événements d’intégrité et de diagnostic qui se retrouvent finalement dans un magasin d’événements pour l’interrogation et l’affichage. Dans une approche de microservices, il est essentiel que différentes équipes s’accordent sur un format de journalisation unique. Il doit y avoir une approche cohérente pour afficher les événements de diagnostic dans l’application.

Examens de santé

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 soit actuellement défectueux en raison d’un incident de processus ou d’un redémarrage de l’ordinateur, le service peut toujours être opérationnel. La dernière chose dont vous avez besoin est de rendre cela pire en effectuant une mise à niveau. La meilleure approche consiste à effectuer une enquête en premier ou à autoriser le temps de récupération du microservice. 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 des contrôles d’intégrité dans ASP.NET section Services principaux de ce guide, nous expliquons comment utiliser une nouvelle bibliothèque HealthChecks ASP.NET dans vos microservices afin qu’elles puissent signaler leur état à un service de surveillance pour prendre les mesures appropriées.

Vous avez également la possibilité d’utiliser une excellente bibliothèque open source appelée AspNetCore.Diagnostics.HealthChecks, disponible sur GitHub et en tant que package NuGet. Cette bibliothèque effectue également des contrôles d’intégrité; avec une touche particulière, elle gère deux types de vérifications :

  • Liveness : vérifie si le microservice est actif, c’est-à-dire s’il est en mesure d’accepter les demandes et de 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, afin que le microservice puisse faire ce qu’il est censé faire.

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

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

Dans les applications monolithiques basées sur un serveur, vous pouvez écrire des journaux dans un fichier sur disque (un fichier journal), puis l’analyser avec n’importe quel outil. Étant donné que l’exécution de l’application est limitée à un serveur fixe ou à une machine virtuelle, elle n’est généralement pas trop complexe pour analyser le flux d’événements. Toutefois, dans une application distribuée où plusieurs services sont exécutés sur de nombreux nœuds d’un cluster orchestrator, la possibilité de mettre en corrélation les événements distribués est un défi.

Une application basée sur un microservice ne doit pas essayer de stocker le flux de sortie d’événements ou de fichiers journaux lui-même, et même de ne pas essayer de gérer le routage des événements vers un emplacement central. Il doit être transparent, c'est-à-dire que chaque processus doit simplement écrire son flux d’événements dans un flux de sortie qui sera collecté par l’infrastructure de l’environnement d’exécution où il s'exécute. Un exemple de ces routeurs de flux d’événements est Microsoft.Diagnostic.EventFlow, qui collecte les flux d’événements à partir de plusieurs sources et les publie dans des systèmes de sortie. Celles-ci peuvent inclure une sortie standard simple pour un environnement de développement ou des systèmes cloud tels qu’Azure Monitor et Diagnostics Azure. Il existe également de bonnes plateformes et outils d’analyse de logs tiers qui peuvent rechercher, alerter, signaler et surveiller les logs, même en temps réel, comme Splunk ou Middleware.

Orchestrateurs gérant les informations de santé et de diagnostic

Lorsque vous créez une application basée sur un microservice, vous devez gérer la complexité. Bien sûr, un seul microservice est simple à traiter, mais des dizaines ou des centaines de types et des milliers d’instances de microservices est un problème complexe. Il ne s’agit pas seulement de créer votre architecture de microservice : vous avez également besoin d’une haute disponibilité, d’une adressabilité, d’une résilience, d’une intégrité et de diagnostics si vous envisagez d’avoir un système stable et cohérent.

Diagramme des clusters fournissant une plateforme de prise en charge pour les microservices.

Figure 4-22. Une plateforme microservice est fondamentale 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 la création d’applications personnalisées avec des approches basées sur des microservices. Ils ne doivent pas se concentrer sur la résolution des problèmes d’infrastructure complexes ; s’ils l’ont fait, le coût d’une application basée sur des microservices serait énorme. Par conséquent, il existe des plateformes orientées microservice, appelées orchestrateurs ou clusters de microservice, qui tentent de résoudre les problèmes difficiles de création et d’exécution d’un service et l’utilisation efficace des ressources d’infrastructure. Cette approche réduit la complexité de la création d’applications qui utilisent une approche de microservices.

Différents orchestrateurs peuvent sembler similaires, mais les diagnostics et les contrôles d’intégrité proposés par chacun d’entre eux diffèrent dans les fonctionnalités et l’état de maturité, parfois en fonction de la plateforme du système d’exploitation, comme expliqué dans la section suivante.

Ressources supplémentaires