Cvičení – implementace odolnosti aplikací

Dokončeno

Projekt eShop má dvě služby, které spolu komunikují pomocí požadavků HTTP. Služba Store volá službu Product, aby získala seznam všech aktuálních produktů, které si můžete koupit.

Aktuální verze aplikace nemá žádné zpracování odolnosti. Pokud služba Product není dostupná, služba Store zákazníkům vrátí chybu a požádá je, aby to zkusili znovu později. Toto chování není dobrým uživatelským zážitkem.

Váš nadřízený vás požádá, abyste do aplikace přidali odolnost, aby služba Store v případě selhání znovu zavolala záložní službu.

V tomto cvičení přidáte odolnost do existující aplikace nativní pro cloud a otestujete opravu.

Otevření vývojového prostředí

Můžete použít codespace GitHubu, který je hostitelem cvičení, nebo cvičení dokončit místně v editoru Visual Studio Code.

Chcete-li použít codespace, vytvořte předem nakonfigurovaný GitHub Codespace pomocí tohoto odkazu pro vytvoření Codespace.

Vytvoření a konfigurace prostoru kódu na GitHubu trvá několik minut. Po dokončení procesu se zobrazí soubory kódu pro cvičení. Kód, který se má použít pro zbytek tohoto modulu, je v adresáři /dotnet-resiliency .

Použijte Visual Studio Code editor, k naklonování úložiště https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative na váš místní počítač. Potom:

  1. Nainstalujte všechny systémové požadavky pro spuštění vývojového kontejneru ve Visual Studio Code.
  2. Ujistěte se, že je Docker spuštěný.
  3. V novém okně editoru Visual Studio Code otevřete složku klonovaného úložiště.
  4. Stisknutím kombinace kláves Ctrl+Shift+P otevřete paletu příkazů.
  5. Hledání: >Dev Containers: Opětovné sestavení a opětovné otevření v kontejneru
  6. V rozevíracím seznamu vyberte eShopLite – dotnet-resiliency. Visual Studio Code vytvoří vývojový kontejner místně.

Sestavení a spuštění aplikace

  1. Na dolním panelu vyberte kartu TERMINÁL a spuštěním následujícího příkazu přejděte do kořenového adresáře kódu:

    cd dotnet-resiliency
    
  2. Spuštěním následujícího příkazu sestavte image aplikace eShop:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Po dokončení sestavení spusťte aplikaci spuštěním následujícího příkazu:

    docker compose up
    
  4. V dolním panelu vyberte kartu PORTY a potom ve sloupci Přeposlaná adresa tabulky vyberte ikonu Otevřít v prohlížeči pro port Front End (32000).

    Pokud aplikaci spouštíte místně, otevřete okno prohlížeče a zobrazte http://localhost:32000/products.

  5. Aplikace eShop by měla být spuštěná. Vyberte položku nabídky Produkty , měla by se zobrazit seznam produktů.

    Snímek obrazovky zobrazující aplikaci eShop spuštěnou v prohlížeči

Testování aktuální odolnosti

Zastavte produktovou službu, abyste viděli, co se s aplikací stane.

  1. Vraťte se do vašeho prostoru kódu a na kartě TERMINAL vyberte + pro otevření nového terminálu bash.

  2. Spuštěním následujícího příkazu Dockeru zobrazte seznam spuštěných kontejnerů:

    docker ps
    

    Měl by se zobrazit seznam aktuálně spuštěných kontejnerů, například:

    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. Vyhledejte ID kontejneru pro kontejner produktových služeb. V předchozím příkladu je ID 6ba80f3c7ab0.

  4. Pomocí tohoto příkazu Dockeru zastavte produktovou službu:

    docker stop <CONTAINER ID>
    

    Kde <CONTAINER ID> je ID, které jste našli v předchozím kroku. Například:

    docker stop 6ba80f3c7ab0
    
  5. Vraťte se na kartu prohlížeče se spuštěnou aplikací a aktualizujte stránku. Měla by se zobrazit chybová zpráva:

    Při načítání našich produktů došlo k potížím. Zkuste to prosím znovu později.

  6. Vraťte se do prostředí codespace a v terminálu vyberte terminál Dockeru a stisknutím kláves Ctrl+C aplikaci zastavte. Měli byste vidět:

    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
    

Přidání odolnosti do aplikace

Prvním postupem, jak zajistit větší odolnost aplikace, je přidání balíčku NuGet Microsoft.Extensions.Http.Resilience do projektu. Pak ho můžete použít v Program.cs.

Přidání balíčku Microsoft.Extensions.Http.Resilience

  1. V codespace přejděte na kartě TERMINAL do složky projektu Store:

    cd Store
    
  2. Spuštěním následujícího příkazu přidejte balíček NuGet odolnosti:

    dotnet add package Microsoft.Extensions.Http.Resilience
    

    Spuštění tohoto příkazu z terminálu ve složce projektu aplikace přidá odkaz na balíček do souboru projektu Store.csproj .

  3. V PRŮZKUMNÍKu bočním panelu vyberte Program.cs.

  4. Na začátek souboru přidejte následující příkaz using:

    using Microsoft.Extensions.Http.Resilience;
    

Přidání standardní strategie odolnosti

  1. Na řádku 13 před ;přidejte tento kód:

    .AddStandardResilienceHandler()
    

    Váš kód by měl vypadat takto:

    builder.Services.AddHttpClient<ProductService>(c =>
    {
        var url = builder.Configuration["ProductEndpoint"] ?? throw new InvalidOperationException("ProductEndpoint is not set");
    
        c.BaseAddress = new(url);
    }).AddStandardResilienceHandler();
    

    Výše uvedený kód přidá do HTTPClient standardní obslužnou rutinu pro odolnost. Obslužná rutina používá všechna výchozí nastavení pro standardní strategii odolnosti.

    V aplikaci nejsou potřeba žádné další změny kódu. Pojďme aplikaci spustit a otestovat odolnost.

  2. Spuštěním následujících příkazů znovu sestavte aplikaci eShop:

    cd ..
    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Po dokončení sestavení spusťte aplikaci spuštěním následujícího příkazu:

    docker compose up
    
  4. Vraťte se na kartu prohlížeče se spuštěnou aplikací a aktualizujte stránku produktu. Měl by se zobrazit seznam produktů.

  5. Vraťte se do vašeho prostoru kódu a na kartě TERMINAL vyberte druhý terminál Bash. Zkopírujte ID KONTEJNERU pro kontejner productservice.

  6. Znovu spusťte příkaz docker stop:

    docker stop <CONTAINER ID>
    
  7. Vraťte se na kartu prohlížeče se spuštěnou aplikací a aktualizujte stránku produktu. Tentokrát by měla trvat o něco déle, než se zobrazí chybová zpráva aplikace:

    Při načítání našich produktů došlo k potížím. Zkuste to prosím znovu později.

    Pojďme se podívat na protokoly a zjistit, jestli naše strategie odolnosti funguje.

  8. Vraťte se do svého codespace a na kartě TERMINAL vyberte terminál Docker.

  9. V terminálu stisknutím kláves Ctrl+C zastavte spuštěnou aplikaci.

  10. Ve zprávách protokolu se posuňte nahoru, dokud nenaleznete odkazy na 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'
    

    Měli byste vidět mnoho podobných zpráv; každý z nich je pokus o opakování. Výše uvedená zpráva ukazuje druhý pokus a čas, který trvalo spuštění.

Konfigurace strategie odolnosti

Když do své aplikace přidáte odolnost, vyvažujete potřebu rychle reagovat na uživatele s nutností nepřetěžovat žádné back-endové služby. Můžete se rozhodnout jenom vy, jestli výchozí možnosti vyhovují potřebám vašich firem.

V tomto příkladu byste chtěli, aby obchodní služba čekala o něco déle, aby měla šanci na zotavení.

  1. V okně kódu pro Program.cs změňte kód na řádku 13 na:

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

    Výše uvedený kód změní výchozí strategii opakování tak, aby měla maximální počet opakování sedm. Pamatujte, že strategie zahrnuje exponenciální zádrž, takže celkový čas je přibližně 5 minut.

  2. Zastavte docker s Ctrl+C. Pak spuštěním následujícího příkazu znovu sestavte aplikaci eShop:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  3. Po dokončení sestavení spusťte aplikaci spuštěním následujícího příkazu:

    docker compose up
    

    Zastavte kontejner back-endové služby v terminálu Bash a aktualizujte eShop. Všimněte si, že zobrazení chybové zprávy trvá déle. Pokud ale zkontrolujete protokoly, uvidíte, že se strategie opakování spustila pouze pětkrát. Poslední zpráva z Polly je:

    Polly.Timeout.TimeoutRejectedException: The operation didn't complete within the allowed timeout of '00:00:30'.
    

    Ve výše uvedené zprávě se dozvíte, že celkový časový limit požadavku zastaví dosažení maximálního počtu opakování. Problém můžete vyřešit zvýšením celkového časového limitu žádosti.

  4. V terminálu aplikaci zastavíte stisknutím kláves Ctrl+C .

  5. V okně kódu pro Program.cs změňte kód na řádku 13 na:

    .AddStandardResilienceHandler(options =>
    {
        options.Retry.RetryCount = 7;
        options.TotalRequestTimeout = new HttpTimeoutStrategyOptions
        {
            Timeout = TimeSpan.FromMinutes(5)
        };
    });
    

    Výše uvedený kód změní celkový časový limit požadavku na 260 sekund, což je teď delší než strategie opakování.

    Díky těmto změnám byste měli mít dostatek času ke spuštění aplikace, zastavení služby produktu, kontrole pokusů o opakování v protokolech terminálu, aktualizaci eShopu, aby se zobrazila zpráva o načítání, a nakonec restartování produktové služby, abyste úspěšně viděli seznam produktů.

  6. Spuštěním následujícího příkazu znovu sestavte aplikaci eShop:

    dotnet publish /p:PublishProfile=DefaultContainer
    
  7. Po dokončení sestavení spusťte aplikaci spuštěním následujícího příkazu:

    docker compose up
    

Otestování nových možností odolnosti

K otestování aplikace v kontejneru použijte rozšíření Dockeru. Rozšíření poskytuje grafické uživatelské rozhraní pro zobrazení a řízení stavu kontejnerů.

  1. V nabídce vlevo vyberte ikonu Docker.

    snímek obrazovky s rozšířením Dockeru, který ukazuje, jak zastavit službu produktů.

  2. Na panelu DOCKER v sekci CONTAINERSklikněte pravým tlačítkem na kontejner products a vyberte Zastavit.

  3. Vraťte se na kartu prohlížeče se spuštěnou aplikací a aktualizujte stránku produktu. Měla by se zobrazit zpráva Načítání....

  4. Vraťte se do pracovního prostoru kódu a na kartě TERMINAL vyberte terminál Docker. Strategie odolnosti funguje.

  5. Na panelu DOCKER v části CONTAINERSklikněte pravým tlačítkem na kontejner produkty a vyberte možnost Spustit.

  6. Vraťte se na kartu prohlížeče se spuštěnou aplikací. Počkejte a aplikace by se měla obnovit se seznamem produktů.

  7. V terminálu zastavte docker pomocí ctrl+C.