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

  1. Installeer systeemopdrachten om Dev Container uit te voeren in Visual Studio Code.
  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: >opnieuw bouwen en opnieuw openen in container
  6. Selecteer eShopLite - dotnet-resiliency in de vervolgkeuzelijst. Visual Studio Code maakt uw ontwikkelcontainer lokaal.

Ontwikkel de app en voer deze uit

  1. Selecteer in het onderste deelvenster het tabblad TERMINAL en voer de volgende opdracht uit naar de hoofdmap van de code:

    cd dotnet-resiliency
    
  2. Voer de volgende opdracht uit om de installatiekopieën van de eShop-app 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 weer te geven http://localhost:32000/products.

  5. De eShop-app moet worden uitgevoerd. Selecteer het menu-item Producten . U ziet nu de lijst met producten.

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

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 productservicecontainer . In het bovenstaande voorbeeld is de id 6ba80f3c7ab0.

  4. 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
    
  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. Probeert u het later nog eens.

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

  1. Navigeer in uw codespace op het tabblad TERMINAL naar de map Store-project :

    cd Store
    
  2. 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 .

  3. Selecteer Program.cs in de zijbalk explorer.

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

    using Microsoft.Extensions.Http.Resilience;
    

Een standaardtolerantiestrategie toevoegen

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

  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 codespace en selecteer op het tabblad TERMINAL de tweede bash-terminal. Kopieer de CONTAINER-id voor de productservicecontainer .

  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. Probeert u het later nog eens.

    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'
    

    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.

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

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

  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 Docker-pictogram .

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

  2. Klik in het DOCKER-deelvenster onder CONTAINERS met de rechtermuisknop op de container producten en selecteer Stoppen.

  3. Ga terug naar het browsertabblad waarop de app wordt uitgevoerd en vernieuw de productpagina. Het bericht Laden... wordt weergegeven.

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

  5. Klik in het DOCKER-deelvenster onder CONTAINERS met de rechtermuisknop op de container producten en selecteer Start.

  6. Ga terug naar het browsertabblad waarop de app wordt uitgevoerd. Wacht en de app moet worden hersteld met de lijst met de producten.

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