Oefening: toepassingstolerantie implementeren

Voltooid

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 u kunt kopen.

De huidige versie van de app heeft geen tolerantieafhandeling. Als de Product-service niet beschikbaar is, geeft de Store-service een foutmelding aan de klanten en vraagt hen om 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 codespacewilt gebruiken, maakt u een vooraf geconfigureerde GitHub Codespace met deze koppeling voor het maken van coderuimten.

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. Dan:

  1. Installeer eventuele systeemorders om Dev Container in Visual Studio Code uit te voeren.
  2. Zorg ervoor dat Docker wordt uitgevoerd.
  3. Open in een nieuw Visual Studio Code-venster de map van de gekloonde opslagplaats
  4. Druk op Ctrl+Shift+P om het opdrachtenpalet te openen.
  5. Zoeken: >Dev-containers: herbouwen en opnieuw openen in container
  6. Selecteer eShopLite - dotnet-resiliency in de vervolgkeuzelijst. Visual Studio Code maakt uw ontwikkelcontainer lokaal.

De app bouwen en uitvoeren

  1. Selecteer in het onderste deelvenster het tabblad TERMINAAL en voer de volgende opdracht uit om naar de hoofdmap van de code te gaan:

    cd dotnet-resiliency
    
  2. Voer de volgende opdracht uit om de eShop-app-images te bouwen:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Zodra de build is voltooid, voert u de volgende opdracht uit om de app te starten:

    docker compose up
    
  4. 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 http://localhost:32000/productsweer te geven.

  5. De eShop-app moet draaien. Selecteer de menuopdracht Producten. U ziet nu de lijst met producten.

    Schermopname van de eShop-app die in een browser wordt uitgevoerd.

De huidige tolerantie testen

Stop de productservice om te zien wat er met de app gebeurt.

  1. Ga terug naar uw coderuimte en selecteer op het tabblad TERMINAL+ om een nieuwe bash-terminal te openen.

  2. 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     
    
  3. Zoek de CONTAINER-id voor de productservice container. In het bovenstaande voorbeeld is de id 6ba80f3c7ab0.

  4. Stop uw productservice met deze docker-opdracht:

    docker stop <CONTAINER ID>
    

    Waar de <CONTAINER ID> de id is die u in de vorige stap hebt gevonden. Bijvoorbeeld:

    docker stop 6ba80f3c7ab0
    
  5. 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. Probeer het later opnieuw.

  6. Ga terug naar uw coderuimte en selecteer in de 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
    

Veerkracht toevoegen aan de app

De eerste stappen om uw app toleranter te maken, zijn het toevoegen van het Microsoft.Extensions.Http.Resilience NuGet-pakket aan het project. U kunt deze vervolgens gebruiken in Program.cs.

Het pakket Microsoft.Extensions.Http.Resilience toevoegen

  1. Op het tabblad TERMINAL in uw coderuimte, navigeert u naar de projectmap Store.

    cd Store
    
  2. Voer de volgende opdracht uit om het NuGet-pakket voor tolerantie toe te voegen:

    dotnet add package Microsoft.Extensions.Http.Resilience
    

    Wanneer u deze opdracht vanuit de terminal in de apps-projectmap uitvoert, wordt de pakketreferentie aan het Store.csproj-projectbestand toegevoegd.

  3. Selecteer Program.csin de zijbalk van EXPLORER.

  4. Voeg boven aan het bestand de volgende using-instructie toe:

    using Microsoft.Extensions.Http.Resilience;
    

Een standaardtolerantiestrategie toevoegen

  1. Op regel 13, vóór ;voegt u deze code toe:

    .AddStandardResilienceHandler()
    

    Uw code moet er 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.

  2. Voer de volgende opdrachten uit om de eShop-app opnieuw te bouwen:

    cd ..
    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Wanneer de build is voltooid, voert u de volgende opdracht uit om de app te starten:

    docker compose up
    
  4. Ga terug naar het browsertabblad waarop de app wordt uitgevoerd en vernieuw de productpagina. U ziet nu de lijst met producten.

  5. Ga terug naar uw coderuimte en selecteer op het tabblad TERMINAL de tweede bash-terminal. Kopieer de CONTAINER-id voor de productservice container.

  6. Voer de docker-stopopdracht opnieuw uit:

    docker stop <CONTAINER ID>
    
  7. 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. Probeer het later opnieuw.

    Laten we de logboeken controleren om te zien of onze tolerantiestrategie werkt.

  8. Ga terug naar uw coderuimte en selecteer op het tabblad TERMINAL de docker terminal.

  9. Druk in de terminal op Ctrl+C om te voorkomen dat de app wordt uitgevoerd.

  10. 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'
    

    U zou veel berichten zoals deze moeten zien; elk bericht is een hernieuwde poging. Het bovenstaande bericht toont de tweede poging en de tijd die nodig was om uit te voeren.

Een tolerantiestrategie configureren

Wanneer u veerkracht toevoegt aan uw app, balanceert u de noodzaak om snel te reageren op uw gebruikers met de behoefte om geen backendservices te overbelasten. Alleen u kunt bepalen of de standaardopties voldoen aan de behoeften van uw bedrijf.

In dit voorbeeld wilt u dat de winkelservice iets langer wacht, zodat de winkelservice de kans krijgt om te herstellen.

  1. Wijzig in het codevenster voor Program.cs de code op regel 13 in:

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

    Met de bovenstaande code worden de standaardinstellingen voor het opnieuw proberen aangepast, zodat het maximale aantal herhalingen op zeven wordt gezet. Onthoud dat de strategie een exponentiële backoff-strategie is, dus de totale tijd is ongeveer 5 minuten.

  2. Stop docker omhoog met Ctrl+C-. Voer vervolgens de volgende opdracht uit om de eShop-app opnieuw te bouwen:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Wanneer de build is voltooid, voert u de volgende opdracht uit om de app te starten:

    docker compose up
    

    Stop de back-end servicecontainer 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 voorkomt dat het maximum aantal nieuwe pogingen wordt bereikt. U kunt het probleem oplossen door de totale time-out van de aanvraag te verhogen.

  4. Druk in de terminal op Ctrl+C- om de app te stoppen.

  5. 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.

  6. Voer de volgende opdracht uit om de eShop-app opnieuw te bouwen:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  7. 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.

  1. Selecteer in het linkermenu het pictogram Docker-.

    Een schermopname van de Docker-extensie, waarin wordt getoond hoe u de productenservice stopt.

  2. Klik in het deelvenster DOCKER- onder CONTAINERSmet de rechtermuisknop op de producten container en selecteer Stop.

  3. Ga terug naar het browsertabblad waarop de app wordt uitgevoerd en vernieuw de productpagina. U zou het bericht Laden... moeten zien.

  4. Ga terug naar uw coderuimte en selecteer op het tabblad TERMINAL de docker terminal. De tolerantiestrategie werkt.

  5. Klik in het deelvenster DOCKER onder CONTAINERSmet de rechtermuisknop op de products container en selecteer Start.

  6. Ga terug naar het browsertabblad waarop de app wordt uitgevoerd. Wacht en de app zou zich moeten herstellen met de lijst van de producten.

  7. Stop docker in de Terminal met Ctrl+C.