Cvičení – implementace odolnosti aplikací

Dokončeno

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

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

Váš nadřízený vás vyzve, abyste do aplikace přidali odolnost, aby Store služba v případě selhání znova volat back-endovou 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.

Pokud chcete použít codespace, vytvořte předem nakonfigurovaný kód 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 .

Pokud chcete použít Visual Studio Code, naklonujte https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative úložiště do místního počítače. Potom:

  1. Nainstalujte všechny požadavky na systém pro spuštění vývojového kontejneru v editoru 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ě.

Sestavte a spusťte aplikaci.

  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 Forwarded Address (Přesměrovaná adresa) v tabulce 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/productsho.

  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 codespace a na kartě TERMINÁL vyberte + nový terminál 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 kontejneru productservice . V předchozím příkladu je ID 6ba80f3c7ab0.

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

    docker stop <CONTAINER ID>
    

    <CONTAINER ID> Kde je ID, které jste našli v předchozím kroku. Pří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 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 tohle:

    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í Microsoft.Extensions.Http.Resilience balíčku NuGet 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 Store project:

    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. Na bočním panelu Průzkumníka 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 měl vypadat přibližně 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 odolnosti. 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 codespace a na kartě TERMINÁL vyberte druhý terminál Bash. Zkopírujte ID KONTEJNERu kontejneru 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 později.

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

  8. Vraťte se do vašeho codespace a na kartě TERMINÁL vyberte terminál Dockeru.

  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 nenajdete 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 služba store čekala o něco déle, aby služba úložiště získala šanci na obnovení.

  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 vyřazení z 7. Mějte na paměti, že strategie je exponenciální zpochybnění, takže celkový čas je přibližně 5 minut.

  2. Zastavte docker up pomocí 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í opakovat 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í pokusů v protokolech terminálu, aktualizaci eShopu, aby se zobrazila zpráva o načítání, a nakonec restartujte produktovou službu, aby se úspěšně zobrazil 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 Dockeru.

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

  2. Na panelu DOCKER v části KONTEJNERY klikněte pravým tlačítkem na kontejner produktů 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 vašeho codespace a na kartě TERMINÁL vyberte terminál Dockeru. Strategie odolnosti funguje.

  5. Na panelu DOCKER v části KONTEJNERY klikněte pravým tlačítkem na kontejner produktů a vyberte 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.