Oefening: toepassingstolerantie implementeren
Het eShop-project heeft twee services die met elkaar communiceren met behulp van HTTP-aanvragen. De Store
service roept de Product
service aan om de lijst op te halen met alle huidige producten die beschikbaar zijn om te kopen.
De huidige versie van de app heeft geen tolerantieafhandeling. Als de Product
service niet beschikbaar is, retourneert de Store
service een fout bij de klanten en wordt hen gevraagd het later opnieuw te proberen. Dit gedrag is geen goede gebruikerservaring.
Uw manager vraagt u om tolerantie toe te voegen aan de app, zodat de Store
service de aanroep van de back-endservice opnieuw probeert uit te voeren als deze mislukt.
In deze oefening voegt u tolerantie toe aan een bestaande cloudeigen app en test u uw oplossing.
De ontwikkelomgeving openen
U kunt ervoor kiezen om een GitHub-coderuimte te gebruiken die als host fungeert voor de oefening of om de oefening lokaal te voltooien in Visual Studio Code.
Als u een codespace wilt gebruiken, maakt u een vooraf geconfigureerde GitHub Codespace met deze koppeling voor het maken van Codespace.
GitHub duurt enkele minuten om de codespace te maken en te configureren. Wanneer het proces is voltooid, ziet u de codebestanden voor de oefening. De code die voor de rest van deze module moet worden gebruikt, bevindt zich in de map /dotnet-resiliency .
Als u Visual Studio Code wilt gebruiken, kloont u de https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative opslagplaats naar uw lokale computer. Daarna kunt u het volgende doen:
- Installeer systeemopdrachten om Dev Container uit te voeren in Visual Studio Code.
- Zorg ervoor dat Docker wordt uitgevoerd.
- Open in een nieuw Visual Studio Code-venster de map van de gekloonde opslagplaats
- Druk op Ctrl+Shift+P om het opdrachtenpalet te openen.
- Zoeken: Dev-containers: >opnieuw bouwen en opnieuw openen in container
- Selecteer eShopLite - dotnet-resiliency in de vervolgkeuzelijst. Visual Studio Code maakt uw ontwikkelcontainer lokaal.
Ontwikkel de app en voer deze uit
Selecteer in het onderste deelvenster het tabblad TERMINAL en voer de volgende opdracht uit naar de hoofdmap van de code:
cd dotnet-resiliency
Voer de volgende opdracht uit om de installatiekopieën van de eShop-app te bouwen:
dotnet publish /p:PublishProfile=DefaultContainer
Zodra de build is voltooid, voert u de volgende opdracht uit om de app te starten:
docker compose up
Selecteer in het onderste deelvenster het tabblad POORTEN en selecteer vervolgens in de kolom Doorgestuurd adres van de tabel het pictogram Openen in browser voor de front-endpoort (32000).
Als u de app lokaal uitvoert, opent u een browservenster om weer te geven
http://localhost:32000/products
.De eShop-app moet worden uitgevoerd. Selecteer het menu-item Producten . U ziet nu de lijst met producten.
De huidige tolerantie testen
Stop de productservice om te zien wat er met de app gebeurt.
Ga terug naar uw coderuimte en selecteer + op het tabblad TERMINAL om een nieuwe bash-terminal te openen.
Voer de volgende Docker-opdracht uit om de actieve containers weer te geven:
docker ps
U ziet nu de lijst met momenteel actieve containers, bijvoorbeeld:
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
Zoek de CONTAINER-id voor de productservicecontainer . In het bovenstaande voorbeeld is de id 6ba80f3c7ab0.
Stop uw productservice met deze docker-opdracht:
docker stop <CONTAINER ID>
Waar de
<CONTAINER ID>
id is die u in de vorige stap hebt gevonden. Voorbeeld:docker stop 6ba80f3c7ab0
Ga terug naar het browsertabblad waarop de app wordt uitgevoerd en vernieuw de pagina. Er wordt een foutbericht weergegeven:
Er is een probleem met het laden van onze producten. Probeert u het later nog eens.
Ga terug naar uw coderuimte en selecteer in TERMINAL de docker-terminal en druk op Ctrl+C om de app te stoppen. U ziet het volgende:
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
Tolerantie toevoegen aan de app
De eerste stappen om uw app toleranter te maken, zijn door het Microsoft.Extensions.Http.Resilience
NuGet-pakket toe te voegen aan het project. U kunt deze vervolgens gebruiken in Program.cs.
Het pakket Microsoft.Extensions.Http.Resilience toevoegen
Navigeer in uw codespace op het tabblad TERMINAL naar de map Store-project :
cd Store
Voer de volgende opdracht uit om het NuGet-pakket voor tolerantie toe te voegen:
dotnet add package Microsoft.Extensions.Http.Resilience
Als u deze opdracht uitvoert vanuit de terminal in de projectmap apps, wordt de pakketreferentie toegevoegd aan het projectbestand Store.csproj .
Selecteer Program.cs in de zijbalk explorer.
Voeg boven aan het bestand de volgende using-instructie toe:
using Microsoft.Extensions.Http.Resilience;
Een standaardtolerantiestrategie toevoegen
Voeg op regel 13, vóór ;, deze code toe:
.AddStandardResilienceHandler()
De code moet er nu als volgt uitzien:
builder.Services.AddHttpClient<ProductService>(c => { var url = builder.Configuration["ProductEndpoint"] ?? throw new InvalidOperationException("ProductEndpoint is not set"); c.BaseAddress = new(url); }).AddStandardResilienceHandler();
Met de bovenstaande code wordt een standaardhandler voor tolerantie toegevoegd aan de HTTPClient. De handler gebruikt alle standaardinstellingen voor de standaardtolerantiestrategie.
Er zijn geen andere codewijzigingen nodig voor uw app. We gaan de app uitvoeren en de tolerantie testen.
Voer de volgende opdrachten uit om de eShop-app opnieuw te bouwen:
cd .. dotnet publish /p:PublishProfile=DefaultContainer
Wanneer de build is voltooid, voert u de volgende opdracht uit om de app te starten:
docker compose up
Ga terug naar het browsertabblad waarop de app wordt uitgevoerd en vernieuw de productpagina. U ziet nu de lijst met producten.
Ga terug naar uw codespace en selecteer op het tabblad TERMINAL de tweede bash-terminal. Kopieer de CONTAINER-id voor de productservicecontainer .
Voer de docker-stopopdracht opnieuw uit:
docker stop <CONTAINER ID>
Ga terug naar het browsertabblad waarop de app wordt uitgevoerd en vernieuw de productpagina. Deze keer duurt het iets langer totdat het foutbericht van de apps wordt weergegeven:
Er is een probleem met het laden van onze producten. Probeert u het later nog eens.
Laten we de logboeken controleren om te zien of onze tolerantiestrategie werkt.
Ga terug naar uw coderuimte en selecteer op het tabblad TERMINAL de docker-terminal .
Druk in de terminal op Ctrl+C om te voorkomen dat de app wordt uitgevoerd.
Schuif in de logboekberichten omhoog totdat u verwijzingen naar Polly vindt.
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'
Als het goed is, ziet u veel berichten zoals deze; elke poging is een nieuwe poging. Het bovenstaande bericht toont de tweede poging en de tijd die nodig was om uit te voeren.
Een tolerantiestrategie configureren
Wanneer u tolerantie toevoegt aan uw app, moet u snel reageren op uw gebruikers, met de noodzaak om geen back-endservices te overbelasten. Alleen u kunt bepalen of de standaardopties voldoen aan de behoeften van uw bedrijf.
In dit voorbeeld wilt u dat de store-service wat langer wacht, zodat de storeservice een kans krijgt om te herstellen.
Wijzig in het codevenster voor Program.cs de code op regel 13 in:
.AddStandardResilienceHandler(options => { options.Retry.MaxRetryAttempts = 7; });
Met de bovenstaande code wordt de standaardinstelling voor opnieuw proberen gewijzigd, zodat het maximum aantal buiten gebruik wordt gesteld aan zeven. Onthoud dat de strategie exponentieel uitstel is, dus de totale tijd is ongeveer 5 minuten.
Stop docker omhoog met Ctrl+C. Voer vervolgens de volgende opdracht uit om de eShop-app opnieuw te bouwen:
dotnet publish /p:PublishProfile=DefaultContainer
Wanneer de build is voltooid, voert u de volgende opdracht uit om de app te starten:
docker compose up
Stop de back-endservicecontainer in de bash-terminal en vernieuw de eShop. Houd er rekening mee dat het langer duurt om het foutbericht te zien. Als u echter de logboeken controleert, kunt u zien dat de strategie voor opnieuw proberen slechts vijf keer opnieuw is geprobeerd. Het laatste bericht van Polly is:
Polly.Timeout.TimeoutRejectedException: The operation didn't complete within the allowed timeout of '00:00:30'.
In het bovenstaande bericht wordt aangegeven dat de totale time-out van de aanvraag stopt met het maximum aantal nieuwe pogingen dat wordt bereikt. U kunt het probleem oplossen door de totale time-out van de aanvraag te verhogen.
Druk in de terminal op Ctrl+C om de app te stoppen.
Wijzig in het codevenster voor Program.cs de code op regel 13 in:
.AddStandardResilienceHandler(options => { options.Retry.RetryCount = 7; options.TotalRequestTimeout = new HttpTimeoutStrategyOptions { Timeout = TimeSpan.FromMinutes(5) }; });
De bovenstaande code wijzigt de totale time-out van de aanvraag in 260 seconden, wat nu langer is dan de strategie voor opnieuw proberen.
Met deze wijzigingen hebt u voldoende tijd om de app uit te voeren, de productservice te stoppen, de terminallogboeken te controleren op nieuwe pogingen, de eShop te vernieuwen om het laadbericht te zien en ten slotte de productservice opnieuw te starten om de lijst met producten te zien.
Voer de volgende opdracht uit om de eShop-app opnieuw te bouwen:
dotnet publish /p:PublishProfile=DefaultContainer
Wanneer de build is voltooid, voert u de volgende opdracht uit om de app te starten:
docker compose up
De nieuwe tolerantieopties testen
Gebruik de Docker-extensie om de app in uw container te testen. De extensie biedt een GUI om de status van containers weer te geven en te beheren.
Selecteer in het linkermenu het Docker-pictogram .
Klik in het DOCKER-deelvenster onder CONTAINERS met de rechtermuisknop op de container producten en selecteer Stoppen.
Ga terug naar het browsertabblad waarop de app wordt uitgevoerd en vernieuw de productpagina. Het bericht Laden... wordt weergegeven.
Ga terug naar uw coderuimte en selecteer op het tabblad TERMINAL de docker-terminal . De tolerantiestrategie werkt.
Klik in het DOCKER-deelvenster onder CONTAINERS met de rechtermuisknop op de container producten en selecteer Start.
Ga terug naar het browsertabblad waarop de app wordt uitgevoerd. Wacht en de app moet worden hersteld met de lijst met de producten.
Stop docker in de terminal met Ctrl+C.