Övning – Implementera programåterhämtning

Slutförd

eShop-projektet har två tjänster som kommunicerar med varandra med hjälp av HTTP-begäranden. Store-tjänsten 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 Product-tjänsten inte är tillgänglig returnerar Store-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 resiliens i appen, så att Store-tjänsten försöker göra om backendtjänstanropet om det misslyckas.

I den här övningen lägger du till motståndskraft 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.

För att använda ett kodutrymmekan du skapa ett förkonfigurerat GitHub Codespace med hjälp av den här länken för att skapa kodutrymmet.

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, klona https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative repositoryt till din lokala dator. Då:

  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: Bygg om och öppna igen i Container
  6. Välj eShopLite – dotnet-resiliens från listrutan. Visual Studio Code skapar din utvecklingscontainer lokalt.

Skapa och köra appen

  1. I den nedre panelen väljer du fliken TERMINAL och kör följande kommando för att gå 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 fliken PORTS och i kolumnen Adressen för vidarebefordran 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 bör vara igång. 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 på fliken TERMINAL väljer du + 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 containern productservice. I exemplet ovan är ID:t 6ba80f3c7ab0.

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

    docker stop <CONTAINER ID>
    

    Där <CONTAINER ID> ä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 att ladda våra produkter. Försök igen senare.

  6. Gå tillbaka till kodområdet och i TERMINAL välj docker-terminalen och tryck 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 till Microsoft.Extensions.Http.Resilience NuGet-paketet i projektet. Du kan sedan använda den i Program.cs.

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

  1. I din koddmiljö, på fliken TERMINAL, navigera till projektmappen Store:

    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
    

    När du kör det här kommandot från terminalen i projektmappen appar läggs paketreferensen till i Store.csproj projektfil.

  3. I sidofältet EXPLORER väljer du Program.cs.

  4. Lägg till följande using-sats överst i filen:

    using Microsoft.Extensions.Http.Resilience;
    

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

  1. Vid rad 13, före ;lägger du till den här koden:

    .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. Låt oss köra appen och testa motståndskraften.

  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 på fliken TERMINAL väljer du den andra bash-terminalen. Kopiera CONTAINER-ID:t för containern productservice.

  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 finns problem med att ladda 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 på fliken TERMINAL väljer du docker-terminalen.

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

  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 tiden det tog att utfö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 tid, för att ge den en chans att återhämta sig.

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

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

    Koden ovan ändrar standardinställningarna för återförsöksstrategin så att det maximala antalet återförsök blir 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. Välj ikonen Docker på den vänstra menyn.

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

  2. I panelen DOCKER under CONTAINERS, högerklickar du på produkter containern och väljer 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 på fliken TERMINAL väljer du docker-terminalen. Motståndskraftsstrategin fungerar.

  5. I panelen DOCKER, under CONTAINERS, högerklickar du på containern produkt och väljer Starta.

  6. Gå tillbaka till webbläsarfliken som kör appen. Vänta, så bör appen återhämta sig och visa listan över produkterna.

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