Övning – Implementera programåterhämtning

Slutförd

eShop-projektet har två tjänster som kommunicerar med varandra med hjälp av HTTP-begäranden. Tjänsten Store anropar Product tjänsten för att hämta listan över alla aktuella produkter som är tillgängliga att köpa.

Den aktuella versionen av appen har ingen återhämtningshantering. Om tjänsten Product inte är tillgänglig Store returnerar tjänsten ett fel till kunderna och ber dem att försöka igen senare. Det här beteendet är inte en bra användarupplevelse.

Din chef ber dig att lägga till återhämtningsförmågan i appen, så att Store tjänsten försöker utföra serverdelstjänstanropet igen om det misslyckas.

I den här övningen lägger du till återhämtning i en befintlig molnbaserad app och testar din korrigering.

Öppna utvecklingsmiljön

Du kan välja att använda ett GitHub-kodområde som är värd för övningen eller slutföra övningen lokalt i Visual Studio Code.

Om du vill använda ett kodområde skapar du ett förkonfigurerat GitHub Codespace med den här länken för att skapa Codespace.

GitHub tar flera minuter att skapa och konfigurera kodområdet. När processen är klar visas kodfilerna för övningen. Koden som ska användas för resten av den här modulen finns i katalogen /dotnet-resiliency .

Om du vill använda Visual Studio Code klonar du lagringsplatsen https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative till den lokala datorn. Sedan:

  1. Installera alla systemkrav för att köra Dev Container i Visual Studio Code.
  2. Kontrollera att Docker körs.
  3. Öppna mappen för den klonade lagringsplatsen i ett nytt Visual Studio Code-fönster
  4. Tryck på Ctrl+Skift+P för att öppna kommandopaletten.
  5. Sök: >Dev Containers: Återskapa och öppna igen i container
  6. Välj eShopLite – dotnet-återhämtning i listrutan. Visual Studio Code skapar din utvecklingscontainer lokalt.

Kompilera och köra appen

  1. I den nedre panelen väljer du fliken TERMINAL och kör följande kommando och går till kodroten:

    cd dotnet-resiliency
    
  2. Kör följande kommando för att skapa eShop-appbilderna:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. När bygget är klart kör du följande kommando för att starta appen:

    docker compose up
    
  4. I den nedre panelen väljer du på fliken PORTar och i kolumnen Vidarebefordrad adress i tabellen väljer du ikonen Öppna i webbläsare för porten Front End (32000).

    Om du kör appen lokalt öppnar du ett webbläsarfönster för att visa http://localhost:32000/products.

  5. eShop-appen ska köras. Välj menyalternativet Produkter . Du bör se listan över produkter.

    Skärmbild som visar eShop-appen som körs i en webbläsare.

Testa den aktuella motståndskraften

Stoppa produkttjänsten för att se vad som händer med appen.

  1. Gå tillbaka till kodområdet och välj + på fliken TERMINAL för att öppna en ny bash-terminal.

  2. Kör följande Docker-kommando för att visa de containrar som körs:

    docker ps
    

    Du bör se listan över containrar som körs just nu, till exempel:

    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. Leta efter CONTAINER-ID:t för produkttjänstcontainern . I exemplet ovan är ID 6ba80f3c7ab0.

  4. Stoppa produkttjänsten med det här Docker-kommandot:

    docker stop <CONTAINER ID>
    

    <CONTAINER ID> Där är det ID som du hittade i föregående steg. Till exempel:

    docker stop 6ba80f3c7ab0
    
  5. Gå tillbaka till webbläsarfliken som kör appen och uppdatera sidan. Du bör se ett felmeddelande:

    Det är problem med att läsa in våra produkter. Försök igen senare.

  6. Gå tillbaka till kodområdet och i TERMINAL väljer du docker-terminalenoch trycker på Ctrl+C för att stoppa appen. Du bör se:

    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
    

Lägga till återhämtning i appen

De första stegen för att göra din app mer elastisk är att lägga Microsoft.Extensions.Http.Resilience till NuGet-paketet i projektet. Du kan sedan använda den i Program.cs.

Lägg till paketet Microsoft.Extensions.Http.Resilience

  1. I kodområdet går du till mappen Store-projektfliken TERMINAL:

    cd Store
    
  2. Kör följande kommando för att lägga till NuGet-paketet för återhämtning:

    dotnet add package Microsoft.Extensions.Http.Resilience
    

    Om du kör det här kommandot från terminalen i mappen apps-projekt lägger du till paketreferensen till projektfilen Store.csproj .

  3. I explorer-sidofältet väljer du Program.cs.

  4. Lägg till följande med hjälp av -instruktionen överst i filen:

    using Microsoft.Extensions.Http.Resilience;
    

Lägga till en standardstrategi för motståndskraft

  1. Lägg till den här koden på rad 13 före ;:

    .AddStandardResilienceHandler()
    

    Koden bör se ut så här:

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

    Koden ovan lägger till en standardresilienshanterare till HTTPClient. Hanteraren använder alla standardinställningar för standardstrategin för motståndskraft.

    Inga andra kodändringar behövs i din app. Nu ska vi köra appen och testa återhämtning.

  2. Kör följande kommandon för att återskapa eShop-appen:

    cd ..
    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. När bygget är klart kör du följande kommando för att starta appen:

    docker compose up
    
  4. Gå tillbaka till webbläsarfliken som kör appen och uppdatera produktsidan. Du bör se listan över produkter.

  5. Gå tillbaka till kodområdet och välj den andra bash-terminalen på fliken TERMINAL . Kopiera CONTAINER-ID:t för productservice-containern .

  6. Kör docker-stoppkommandot igen:

    docker stop <CONTAINER ID>
    
  7. Gå tillbaka till webbläsarfliken som kör appen och uppdatera produktsidan. Den här gången bör det ta lite längre tid innan du ser appfelmeddelandet:

    Det är problem med att läsa in våra produkter. Försök igen senare.

    Nu ska vi kontrollera loggarna för att se om vår återhämtningsstrategi fungerar.

  8. Gå tillbaka till kodområdet och välj docker-terminalenfliken TERMINAL.

  9. Tryck på Ctrl+C i terminalen för att stoppa körningen av appen.

  10. Rulla uppåt i loggmeddelandena tills du hittar referenser till 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'
    

    Du bör se många meddelanden som detta. var och en är ett återförsök. Ovanstående meddelande visar det andra försöket och den tid det tog att köra.

Konfigurera en återhämtningsstrategi

När du lägger till återhämtning i din app balanserar du behovet av att svara snabbt på dina användare, med behovet av att inte överbelasta några serverdelstjänster. Det är bara du som kan avgöra om standardalternativen uppfyller företagets behov.

I det här exemplet vill du att butikstjänsten ska vänta lite längre för att ge butikstjänsten en chans att återställa.

  1. I kodfönstret för Program.cs ändrar du koden på rad 13 till:

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

    Koden ovan ändrar återförsöksstrategin som standard så att det maximala antalet drar sig tillbaka till sju. Kom ihåg att strategin är en exponentiell backoff, så den totala tiden är cirka 5 minuter.

  2. Stoppa docker med Ctrl+C. Kör sedan följande kommando för att återskapa eShop-appen:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. När bygget är klart kör du följande kommando för att starta appen:

    docker compose up
    

    Stoppa serverdelstjänstcontainern i bash-terminalen och uppdatera eShop. Observera att det tar längre tid att se felmeddelandet. Om du kontrollerar loggarna kan du dock se att återförsöksstrategin bara har gjorts om fem gånger. Det sista meddelandet från Polly är:

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

    Meddelandet ovan visar att den totala tidsgränsen för begäran hindrar det maximala antalet återförsök från att nås. Du kan åtgärda problemet genom att öka den totala tidsgränsen för begäran.

  4. I terminalen trycker du på Ctrl+C för att stoppa appen.

  5. I kodfönstret för Program.cs ändrar du koden på rad 13 till:

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

    Koden ovan ändrar den totala tidsgränsen för begäran till 260 sekunder, vilket nu är längre än återförsöksstrategin.

    Med dessa ändringar bör du ha tillräckligt med tid för att köra appen, stoppa produkttjänsten, kontrollera terminalloggarna för återförsök, uppdatera eShop för att se inläsningsmeddelandet och slutligen starta om produkttjänsten för att se listan över produkter.

  6. Kör följande kommando för att återskapa eShop-appen:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  7. När bygget är klart kör du följande kommando för att starta appen:

    docker compose up
    

Testa de nya återhämtningsalternativen

Om du vill testa appen i containern använder du Docker-tillägget. Tillägget tillhandahåller ett GUI för att visa och kontrollera containrarnas tillstånd.

  1. På den vänstra menyn väljer du Docker-ikonen .

    En skärmbild av Docker-tillägget som visar hur du stoppar produkttjänsten.

  2. Högerklicka på produktcontainern under CONTAINRAR på DOCKER-panelen och välj Stoppa.

  3. Gå tillbaka till webbläsarfliken som kör appen och uppdatera produktsidan. Du bör se meddelandet Läser in...

  4. Gå tillbaka till kodområdet och välj docker-terminalenfliken TERMINAL. Motståndskraftsstrategin fungerar.

  5. Högerklicka på produktcontainern under CONTAINRAR på DOCKER-panelen och välj Starta.

  6. Gå tillbaka till webbläsarfliken som kör appen. Vänta och appen bör återställas med listan över produkter.

  7. I terminalen stoppar du docker med Ctrl+C.