SOMMAIRE

Envie d’aller plus loin ? Échangez directement avec l’un de nos experts.

Le but de cette série d’articles est de présenter les principes de la technologie .NET Aspire, au travers de la mise en place d’une application « cloud native », que nous commencerons par définir. 

Partie 1 :

Partie introductive, pour présenter les enjeux et les solutions apportées par .NET Aspire. 

Partie 2 :

Partie codage, pour illustrer l’adaptation d’une application distribuée existante. 

Partie 3 :

Suite de la partie codage, pour illustrer la découverte de services et ajouter un composant d’intégration. 

Partie 4 :

Suite et fin, pour illustrer le déploiement de notre application distribuée. 

Le code de la solution est disponible sur ce lien.

Nous abordons dans cet article la Partie 2.  

Le deuxième article de cette série nous a permis d’illustrer 3 des blocs fondamentaux de .NET Aspire : 

  • Les paramètres par défaut (« Smart Defaults »), 
  • Le Tableau de bord.
  • L’orchestration. 

Ici nous aborderons 2 autres blocs : 

  1. La découverte de services,
  2. Les intégrations.   

Nous terminerons l’article par un petit exemple de la mise en œuvre du load-balancing avec .NET Aspire. 

Etape 3 : mise en place de la découverte de services 

Pour rappel la configuration du projet Web définissait l’URL d’appel du projet Api de façon « statique » : 

La découverte de services (ou « Service discovery« ) de .NET Aspire est la technique permettant d’invoquer un service de l’application par son point de terminaison avec une syntaxe simplifiée, par exemple « https://<nom_du_service>« .  

C’est le rôle de l’orchestrateur de résoudre ce point de terminaison en le transformant en une Url réelle. 

Découverte de services par référence 

Nous modifions le fichier Program.cs du projet AppHost afin de référencer le projet Api dans le projet Web : 

Ce code demande à l’orchestrateur de fournir au service web les informations de découverte de service permettant d’invoquer le service api. 

Note : 

Nous pouvons le constater en consultant les variables d’environnement du service weatherforecast-web dans le Tableau de bord : le service a à sa disposition une variable permettant d’invoquer le service weatherforecast-api en HTTPS ou en HTTP. 

Configuration du point de terminaison 

La configuration du point de terminaison peut maintenant être simplifiée ainsi :

Note : 

La syntaxe « https+http:// » indique simplement que l’un ou l’autre des protocoles est utilisable pour invoquer l’api. 

SI nous lançons l’application .NET Aspire, nous pouvons constater dans la console ou dans les logs structurés que les appels sont correctement résolus : 

Etape 4 : utilisation des intégrations 

Faisons un état des lieux de notre application distribuée : 

  • Nous avons un projet web qui affiche les données météo. 
  • Ce projet invoque une api qui lui fournit les informations. 

C’est bien, mais un problème subsiste : les données météo changent à chaque invocation de l’api, ce qui n’est pas très cohérent !… 

Pour corriger ce problème nous allons mettre en place un cache de sortie de notre api, afin que les données ne changent pas systématiquement. 

C’est là qu’interviennent les intégrations de .NET Aspire. Comme nous allons le constater, ils sont simples à utiliser, et ils s’intègrent parfaitement au Tableau de bord.  

Ici ce sera l’intégration “OutputCache” de Redis.  

Ajout d’une intégration pour la gestion du cache 

Pour ajouter le package, nous faisons un clic doit sur le nœud Dépendances du projet AppHost, puis nous sélectionnons le menu « Ajouter le package .NET Aspire » : 

Visual Studio affiche alors la liste des packages disponibles. Celui qui nous intéresse est Aspire.Hosting.Redis : 

Note : 

Les intégrations utilisables côté AppHost sont filtrées (automatiquement) avec les attributs suivants : 

Ajout du service de cache 

L’étape suivante est de déclarer un service de cache dans le projet AppHost, et de le référencer uniquement dans le service api.

Encore une fois le nom que nous donnons au service redis est important à conserver, car il sera utilisé pour configurer l’accès à ce service dans le projet Api (cf point “Ajout des middlewares de caching”, plus bas). 

Ajout du caching HTTP dans l’API 

Le caching HTTP a pour but de mettre en cache les réponses d’une API. Le Contrôleur de l’API est ainsi invoqué une première fois pour récupérer sa réponse, et à chaque appel suivant c’est le mécanisme de caching qui fournira les données (en tout cas tant que la durée de mise en cache n’est pas dépassée !). 

ASP.NET Core fournit nativement un mécanisme de caching, mais l’intérêt sera ici de profiter de tous les avantages fournis par un package .NET Aspire dédié au caching.  

Nous devons à présent adapter le projet Api pour qu’il utilise le middleware de caching fourni par .NET Aspire pour Redis : 

  • Clic doit sur le nœud Dépendances du projet Api 
  • Clic sur le menu « Ajouter le package .NET Aspire » 
  • Installation du package Aspire.StackExchange.Redis.OutputCaching  

 Comme l’indique la description du package, celui-ci fournit tous les services de santé, de log et de télémétrie, d’où son intérêt à la place du middleware de caching par défaut de ASP.NET Core. 

Note : 

Les intégrations utilisables côté projet « client » sont filtrés (automatiquement) avec les attributs suivants : 

Ajout du middleware de caching 

Le fichier Program.cs du projet Api doit inclure les lignes suivantes à présent, afin de nous permettre d’activer le caching de sortie du contrôleurs : 

Mise en place du cache HTTP de sortie  

La dernière étape est l’activation du cache sur WeatherForecastController : 

Note : 

Ici les données seront mises en cache pendant 1 heure, qui est donc la durée de confiance que nous accordons à notre Api de prévision météo 😊 ! 

Test final 

Dans le Tableau de bord, nous voyons à présent 3 services, 2 sous forme de projets et 1 qui s’exécute comme un Container Docker, qui a été installé et lancé au moment de l’exécution de la solution : 

Note : 

Il est bien sûr possible d’utiliser un service Redis déjà en exécution, il suffit pour cela d’utiliser la méthode builder.AddConnectionString() :

Le principe est décrit ici.

Plusieurs appels successifs (en-dessous d’1 heure !) fournissent à présent les mêmes données. 

Côté logging, on constate l’ajout des données dans le cache sur le 1er appel :

… puis l’extraction de ces données sur les appels suivants : 

Note : 

Il est possible d’ajouter des services complémentaires à Redis, tels que Redis Insights, ou Redis Commander, afin de piloter la gestion des données en cache, simplement par l’ajout des méthodes .With…() correspondantes (cf https://learn.microsoft.com/en-us/dotnet/aspire/caching/stackexchange-redis-integration?tabs=dotnet-cli&pivots=redis#add-redis-resource-with-redis-insights et https://learn.microsoft.com/en-us/dotnet/aspire/caching/stackexchange-redis-integration?tabs=dotnet-cli&pivots=redis#add-redis-resource-with-redis-commander). 

Etape 5 : mise en place du load balancing 

.NET Aspire nous permet de profiter de façon extrêmement simple du load balancing, en utilisant plusieurs instances de notre site web afin de supporter les montées en charge. 

Le nombre d’instances n’est pas configurable dynamiquement, mais le but est de permettre de vérifier que l’application supporte bien la charge avec plusieurs frontaux. 

Il suffit ainsi d’ajouter le code suivant au service web, dans le projet AppHost: 

Grâce à cette ligne, l’application exécute à présent 3 instances simultanées du service web, comme le montre le Tableau de bord : 

Chaque service web répond sur le même point de terminaison, mais on peut constater en lançant plusieurs navigateurs que ce sont des instances différentes qui répondent : 

Conclusion

Cela termine notre 3ème partie de la découverte de .NET Aspire. 

Grâce à .NET Aspire nous avons pu simplifier la configuration des communications inter-projets, et intégrer des services de caching complètement observables dans le Tableau de bord. 

Nous avons pu aussi profiter du load-balancing en modifiant le nombre d'instances du frontal web. Bien entendu, provisionner plusieurs instances d'un process sur une même machine, ça ne sert pas à grand-chose…  La réponse sera apportée dans la 4ème et dernière partie…! 

Ne ratez plus aucune actualité avec la newsletter mensuelle de SoftFluent

Newsletter SoftFluent