Cvičení – implementace odolnosti aplikací
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:
- Nainstalujte všechny systémové požadavky pro spuštění vývojového kontejneru ve Visual Studio Code.
- Ujistěte se, že je Docker spuštěný.
- V novém okně editoru Visual Studio Code otevřete složku klonovaného úložiště.
- Stisknutím kombinace kláves Ctrl+Shift+P otevřete paletu příkazů.
- Hledání: >Dev Containers: Opětovné sestavení a opětovné otevření v kontejneru
- V rozevíracím seznamu vyberte eShopLite – dotnet-resiliency. Visual Studio Code vytvoří vývojový kontejner místně.
Sestavení a spuštění aplikace
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
Spuštěním následujícího příkazu sestavte image aplikace eShop:
dotnet publish /p:PublishProfile=DefaultContainer
Po dokončení sestavení spusťte aplikaci spuštěním následujícího příkazu:
docker compose up
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
.Aplikace eShop by měla být spuštěná. Vyberte položku nabídky Produkty , měla by se zobrazit seznam produktů.
Testování aktuální odolnosti
Zastavte produktovou službu, abyste viděli, co se s aplikací stane.
Vraťte se do vašeho prostoru kódu a na kartě TERMINAL vyberte + pro otevření nového terminálu bash.
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
Vyhledejte ID kontejneru pro kontejner produktových služeb. V předchozím příkladu je ID 6ba80f3c7ab0.
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
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.
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
V codespace přejděte na kartě TERMINAL do složky projektu Store:
cd Store
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 .
V PRŮZKUMNÍKu bočním panelu vyberte Program.cs.
Na začátek souboru přidejte následující příkaz using:
using Microsoft.Extensions.Http.Resilience;
Přidání standardní strategie odolnosti
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.
Spuštěním následujících příkazů znovu sestavte aplikaci eShop:
cd .. dotnet publish /p:PublishProfile=DefaultContainer
Po dokončení sestavení spusťte aplikaci spuštěním následujícího příkazu:
docker compose up
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ů.
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.
Znovu spusťte příkaz docker stop:
docker stop <CONTAINER ID>
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.
Vraťte se do svého codespace a na kartě TERMINAL vyberte terminál Docker.
V terminálu stisknutím kláves Ctrl+C zastavte spuštěnou aplikaci.
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í.
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.
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
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.
V terminálu aplikaci zastavíte stisknutím kláves Ctrl+C .
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ů.
Spuštěním následujícího příkazu znovu sestavte aplikaci eShop:
dotnet publish /p:PublishProfile=DefaultContainer
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ů.
V nabídce vlevo vyberte ikonu Docker.
Na panelu DOCKER v sekci CONTAINERSklikněte pravým tlačítkem na kontejner products a vyberte Zastavit.
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í....
Vraťte se do pracovního prostoru kódu a na kartě TERMINAL vyberte terminál Docker. Strategie odolnosti funguje.
Na panelu DOCKER v části CONTAINERSklikněte pravým tlačítkem na kontejner produkty a vyberte možnost Spustit.
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ů.
V terminálu zastavte docker pomocí ctrl+C.