Övning – Implementera programåterhämtning
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å:
- Installera alla systemkrav för att köra Dev Container i Visual Studio Code.
- Kontrollera att Docker körs.
- Öppna mappen för den klonade lagringsplatsen i ett nytt Visual Studio Code-fönster
- Tryck på Ctrl+Skift+P för att öppna kommandopaletten.
- Sök: >Dev Containers: Bygg om och öppna igen i Container
- Välj eShopLite – dotnet-resiliens från listrutan. Visual Studio Code skapar din utvecklingscontainer lokalt.
Skapa och köra appen
I den nedre panelen väljer du fliken TERMINAL och kör följande kommando för att gå till kodroten:
cd dotnet-resiliencyKör följande kommando för att skapa eShop-appbilderna:
dotnet publish /p:PublishProfile=DefaultContainerNär bygget är klart kör du följande kommando för att starta appen:
docker compose upI 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.eShop-appen bör vara igång. Välj menyalternativet Produkter. Du bör se listan över produkter.
Testa den aktuella motståndskraften
Stoppa produkttjänsten för att se vad som händer med appen.
Gå tillbaka till kodområdet och på fliken TERMINAL väljer du + för att öppna en ny bash-terminal.
Kör följande Docker-kommando för att visa de containrar som körs:
docker psDu 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 minutesLeta efter CONTAINER-ID:t för containern productservice. I exemplet ovan är ID:t 6ba80f3c7ab0.
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 6ba80f3c7ab0Gå 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.
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
I din koddmiljö, på fliken TERMINAL, navigera till projektmappen Store:
cd StoreKör följande kommando för att lägga till NuGet-paketet för återhämtning:
dotnet add package Microsoft.Extensions.Http.ResilienceNär du kör det här kommandot från terminalen i projektmappen appar läggs paketreferensen till i Store.csproj projektfil.
I sidofältet EXPLORER väljer du Program.cs.
Lägg till följande using-sats överst i filen:
using Microsoft.Extensions.Http.Resilience;
Lägga till en standardstrategi för motståndskraft
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.
Kör följande kommandon för att återskapa eShop-appen:
cd .. dotnet publish /p:PublishProfile=DefaultContainerNär bygget är klart kör du följande kommando för att starta appen:
docker compose upGå tillbaka till webbläsarfliken som kör appen och uppdatera produktsidan. Du bör se listan över produkter.
Gå tillbaka till kodområdet och på fliken TERMINAL väljer du den andra bash-terminalen. Kopiera CONTAINER-ID:t för containern productservice.
Kör docker-stoppkommandot igen:
docker stop <CONTAINER ID>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.
Gå tillbaka till kodområdet och på fliken TERMINAL väljer du docker-terminalen.
I terminalen trycker du på Ctrl+C för att stoppa att appen körs.
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.
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.
Stoppa docker med Ctrl+C. Kör sedan följande kommando för att återskapa eShop-appen:
dotnet publish /p:PublishProfile=DefaultContainerNär bygget är klart kör du följande kommando för att starta appen:
docker compose upStoppa 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.
I terminalen trycker du på Ctrl+C för att stoppa appen.
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.
Kör följande kommando för att återskapa eShop-appen:
dotnet publish /p:PublishProfile=DefaultContainerNä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.
Välj ikonen Docker på den vänstra menyn.
I panelen DOCKER under CONTAINERS, högerklickar du på produkter containern och väljer Stoppa.
Gå tillbaka till webbläsarfliken som kör appen och uppdatera produktsidan. Du bör se meddelandet Läser in....
Gå tillbaka till kodområdet och på fliken TERMINAL väljer du docker-terminalen. Motståndskraftsstrategin fungerar.
I panelen DOCKER, under CONTAINERS, högerklickar du på containern produkt och väljer Starta.
Gå tillbaka till webbläsarfliken som kör appen. Vänta, så bör appen återhämta sig och visa listan över produkterna.
I terminalen stoppar du docker med Ctrl+C.