Exercice - Implémenter la résilience des applications

Effectué

Le projet eShop a deux services qui communiquent entre eux à l’aide de requêtes HTTP. Le Store service appelle le Product service pour obtenir la liste de tous les produits actuellement disponibles à l'achat.

La version actuelle de l’application n’a aucune gestion de résilience. Si le Product service n’est pas disponible, le Store service retourne une erreur aux clients et lui demande de réessayer ultérieurement. Ce comportement n’est pas une bonne expérience utilisateur.

Votre responsable vous demande d’ajouter une résilience à l’application afin que le service Store retente l’appel du service back-end en cas d’échec.

Dans cet exercice, vous ajoutez la résilience à une application cloud native existante et testez votre correctif.

Ouvrez l’environnement de développement

Vous pouvez choisir d’utiliser un codespace GitHub qui héberge l’exercice ou effectuer l’exercice localement dans Visual Studio Code.

Pour utiliser un codespace, créez un codespace GitHub préconfiguré avec ce lien de création de codespace.

GitHub prend plusieurs minutes pour créer et configurer l’espace de code. Une fois le processus terminé, vous voyez les fichiers de code de l’exercice. Le code à utiliser pour le reste de ce module se trouve dans le répertoire /dotnet-resiliency .

Pour utiliser Visual Studio Code, clonez le référentiel https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative sur votre ordinateur local. Ensuite :

  1. Installez les éléments système requis pour exécuter Dev Container dans Visual Studio Code.
  2. Vérifiez que Docker est en cours d’exécution.
  3. Dans une nouvelle fenêtre Visual Studio Code, ouvrez le dossier du référentiel cloné.
  4. Appuyez sur Ctrl+Maj+P pour ouvrir la palette de commandes.
  5. Recherche : >Dev Containers : Reconstruire et rouvrir dans un conteneur
  6. Sélectionnez eShopLite - dotnet-resiliency dans la liste déroulante. Visual Studio Code crée votre conteneur de développement localement.

Générer et exécuter l’application

  1. Dans le volet inférieur, sélectionnez l’onglet TERMINAL et exécutez la commande suivante pour accéder à la racine du code :

    cd dotnet-resiliency
    
  2. Exécutez la commande suivante pour générer les images de l’application eShop :

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Une fois la build terminée, exécutez la commande suivante pour démarrer l’application :

    docker compose up
    
  4. Dans le volet inférieur, sélectionnez l’onglet PORTS , puis, dans la colonne Adresse transférée du tableau, sélectionnez l’icône Ouvrir dans le navigateur pour le port frontal (32000).

    Si vous exécutez l’application localement, ouvrez une fenêtre de navigateur pour afficher http://localhost:32000/products.

  5. L’application eShop doit être en cours d’exécution. Sélectionnez l’élément de menu Produits . Vous devez voir la liste des produits.

    Capture d’écran montrant l’application eShop s’exécutant dans un navigateur.

Tester la résilience actuelle

Arrêtez le service produit pour voir ce qui arrive à l’application.

  1. Revenez à votre espace de code et, dans l’onglet TERMINAL , sélectionnez + pour ouvrir un nouveau terminal bash.

  2. Exécutez la commande Docker suivante pour répertorier les conteneurs en cours d’exécution :

    docker ps
    

    La liste des conteneurs en cours d’exécution doit s’afficher, par exemple :

    CONTAINER ID   IMAGE                                                                            COMMAND                  CREATED          STATUS          PORTS                                                        NAMES
    c08285e8aaa4   storeimage                                                                       "dotnet Store.dll"       8 minutes ago    Up 8 minutes    80/tcp, 443/tcp, 0.0.0.0:5902->8080/tcp, :::5902->8080/tcp   eshoplite-frontend-1
    6ba80f3c7ab0   productservice                                                                   "dotnet Products.dll"    8 minutes ago    Up 8 minutes    80/tcp, 443/tcp, 0.0.0.0:5200->8080/tcp, :::5200->8080/tcp   eshoplite-backend-1
    cd0c822a5222   vsc-eshoplite-958868d22c9851dd911b2423199bfc782861d1a8f7afac48e5096a1b7516082f   "/bin/sh -c 'echo Co…"   27 minutes ago   Up 27 minutes     
    
  3. Recherchez l’ID CONTENEUR du conteneur productservice . Dans l’exemple ci-dessus, l’ID est 6ba80f3c7ab0.

  4. Arrêtez votre service de produit avec cette commande Docker :

    docker stop <CONTAINER ID>
    

    <CONTAINER ID> est l'ID que vous avez trouvé à l'étape précédente. Par exemple:

    docker stop 6ba80f3c7ab0
    
  5. Revenez à l’onglet du navigateur exécutant l’application et actualisez la page. Un message d’erreur doit s’afficher :

    Il y a un problème de chargement de nos produits. Réessayez plus tard.

  6. Revenez à votre espace de code, puis, dans le TERMINAL , sélectionnez le terminal Docker , puis appuyez sur Ctrl+C pour arrêter l’application. Vous devriez voir :

    Gracefully stopping... (press Ctrl+C again to force)
    Aborting on container exit...
    [+] Stopping 2/1
     ✔ Container eshoplite-frontend-1  Stopped                                                                      0.3s 
     ✔ Container eshoplite-backend-1   Stopped                                                                      0.0s 
    canceled
    

Ajouter une résilience à l’application

Les premières étapes pour rendre votre application plus résiliente sont d’ajouter le Microsoft.Extensions.Http.Resilience package NuGet au projet. Vous pouvez ensuite l’utiliser dans Program.cs.

Ajouter le package Microsoft.Extensions.Http.Resilience

  1. Dans votre espace de code, sous l’onglet TERMINAL , accédez au dossier du projet Store :

    cd Store
    
  2. Exécutez la commande suivante pour ajouter le package NuGet de résilience :

    dotnet add package Microsoft.Extensions.Http.Resilience
    

    L’exécution de cette commande à partir du terminal dans le dossier du projet d’applications ajoute la référence de package au fichier projet Store.csproj .

  3. Dans la barre latérale de l’Explorateur , sélectionnez Program.cs.

  4. Au début du fichier, ajoutez l’instruction using suivante :

    using Microsoft.Extensions.Http.Resilience;
    

Ajouter une stratégie de résilience standard

  1. À la ligne 13, avant ;, ajoutez ce code :

    .AddStandardResilienceHandler()
    

    Votre code doit ressembler à ceci :

    builder.Services.AddHttpClient<ProductService>(c =>
    {
        var url = builder.Configuration["ProductEndpoint"] ?? throw new InvalidOperationException("ProductEndpoint is not set");
    
        c.BaseAddress = new(url);
    }).AddStandardResilienceHandler();
    

    Le code ci-dessus ajoute un gestionnaire de résilience standard à HTTPClient. Le gestionnaire utilise tous les paramètres par défaut pour la stratégie de résilience standard.

    Aucune autre modification de code n’est nécessaire à votre application. Nous allons exécuter l’application et tester la résilience.

  2. Exécutez les commandes suivantes pour reconstruire l’application eShop :

    cd ..
    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Une fois la build terminée, exécutez la commande suivante pour démarrer l’application :

    docker compose up
    
  4. Revenez à l’onglet du navigateur exécutant l’application et actualisez la page du produit. Vous devez voir la liste des produits.

  5. Revenez à votre espace de code et, dans l’onglet TERMINAL , sélectionnez le deuxième terminal bash. Copiez l’ID CONTENEUR du conteneur productservice .

  6. Réexécutez la commande docker stop :

    docker stop <CONTAINER ID>
    
  7. Revenez à l’onglet du navigateur exécutant l’application et actualisez la page du produit. Cette fois, cela devrait prendre un peu plus de temps jusqu’à ce que vous voyiez le message d’erreur des applications :

    Il y a un problème de chargement de nos produits. Réessayez plus tard.

    Vérifions les logs pour voir si notre stratégie de résilience fonctionne.

  8. Revenez à votre espace de code et, dans l’onglet TERMINAL , sélectionnez le terminal Docker .

  9. Dans le terminal, appuyez sur Ctrl+C pour arrêter l’exécution de l’application.

  10. Dans les messages de journal, faites défiler jusqu’à ce que vous trouviez des références à Polly.

    eshoplite-frontend-1  | warn: Polly[3]
    eshoplite-frontend-1  |       Execution attempt. Source: 'ProductService-standard//Standard-Retry', Operation Key: '', Result: 'Name or service not known (backend:8080)', Handled: 'True', Attempt: '2', Execution Time: '27.2703'
    

    Vous devriez voir de nombreux messages comme ceci ; chacun d’eux est une nouvelle tentative. Le message ci-dessus montre la deuxième tentative et le temps nécessaire à l’exécution.

Configurer une stratégie de résilience

Lorsque vous ajoutez une résilience à votre application, vous équilibrez la nécessité de répondre rapidement à vos utilisateurs, avec la nécessité de ne pas surcharger les services back-end. Seuls vous pouvez décider si les options par défaut répondent aux besoins de vos entreprises.

Dans cet exemple, vous souhaitez que le service de magasin attende un peu plus longtemps pour permettre au service de magasin de récupérer.

  1. Dans la fenêtre de code de Program.cs, remplacez le code de la ligne 13 par :

    .AddStandardResilienceHandler(options =>
    {
        options.Retry.MaxRetryAttempts = 7;
    });
    

    Le code ci-dessus modifie la stratégie par défaut de nouvelle tentative pour avoir au maximum sept retraits. N’oubliez pas que la stratégie est un backoff exponentiel, donc le temps total est d’environ 5 minutes.

  2. Arrêtez docker avec le raccourci Ctrl+C. Exécutez ensuite la commande suivante pour reconstruire l’application eShop :

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Une fois la build terminée, exécutez la commande suivante pour démarrer l’application :

    docker compose up
    

    Arrêtez le conteneur de service principal dans le terminal bash et actualisez l’eShop. Notez qu’il faut plus de temps pour voir le message d’erreur. Si vous vérifiez toutefois les journaux, vous pouvez voir que la stratégie de nouvelle tentative n’a été retentée que cinq fois. Le dernier message de Polly est :

    Polly.Timeout.TimeoutRejectedException: The operation didn't complete within the allowed timeout of '00:00:30'.
    

    Le message ci-dessus vous indique que le délai d’expiration total de la requête empêche le nombre maximal de nouvelles tentatives d’être atteintes. Vous pouvez résoudre le problème en augmentant le délai d’expiration total de la demande.

  4. Dans le terminal, appuyez sur Ctrl+C pour arrêter l’application.

  5. Dans la fenêtre de code de Program.cs, remplacez le code de la ligne 13 par :

    .AddStandardResilienceHandler(options =>
    {
        options.Retry.RetryCount = 7;
        options.TotalRequestTimeout = new HttpTimeoutStrategyOptions
        {
            Timeout = TimeSpan.FromMinutes(5)
        };
    });
    

    Le code ci-dessus modifie le délai d’expiration total de la requête à 260 secondes, ce qui est désormais plus long que la stratégie de nouvelle tentative.

    Avec ces modifications, vous devez avoir suffisamment de temps pour exécuter l’application, arrêter le service produit, vérifier les journaux du terminal pour les tentatives de réessai, actualiser l’eShop pour constater le message de chargement, et enfin redémarrer le service produit pour afficher la liste des produits.

  6. Exécutez la commande suivante pour reconstruire l’application eShop :

    dotnet publish /p:PublishProfile=DefaultContainer
    
  7. Une fois la build terminée, exécutez la commande suivante pour démarrer l’application :

    docker compose up
    

Tester les nouvelles options de résilience

Pour tester l’application dans votre conteneur, utilisez l’extension Docker. L’extension fournit une interface graphique graphique pour afficher et contrôler l’état des conteneurs.

  1. Dans le menu de gauche, sélectionnez l’icône Docker .

    Capture d’écran de l’extension Docker, montrant comment arrêter le service de produits.

  2. Dans le panneau DOCKER , sous CONTENEURS, cliquez avec le bouton droit sur le conteneur de produits , puis sélectionnez Arrêter.

  3. Revenez à l’onglet du navigateur exécutant l’application et actualisez la page du produit. Vous devriez voir le message Chargement... s’afficher.

  4. Revenez à votre espace de code et, dans l’onglet TERMINAL , sélectionnez le terminal Docker . La stratégie de résilience fonctionne.

  5. Dans le panneau DOCKER , sous CONTENEURS, cliquez avec le bouton droit sur le conteneur de produits , puis sélectionnez Démarrer.

  6. Revenez à l’onglet du navigateur exécutant l’application. Patientez, l’application devrait afficher la liste des produits.

  7. Dans le terminal, arrêtez docker avec Ctrl+C.