Cvičení – implementace odolnosti aplikací
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:
- Nainstalujte všechny požadavky na systém pro spuštění vývojového kontejneru v editoru 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ě.
Sestavte a spusťte aplikaci.
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 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/products
ho.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 codespace a na kartě TERMINÁL vyberte + nový terminál 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 kontejneru productservice . V předchozím příkladu je ID 6ba80f3c7ab0.
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
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.
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
V codespace přejděte na kartě TERMINAL do složky Store project:
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 .
Na bočním panelu Průzkumníka 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 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.
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 codespace a na kartě TERMINÁL vyberte druhý terminál Bash. Zkopírujte ID KONTEJNERu kontejneru 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 později.
Pojďme se podívat na protokoly a zjistit, jestli naše strategie odolnosti funguje.
Vraťte se do vašeho codespace a na kartě TERMINÁL vyberte terminál Dockeru.
V terminálu stisknutím kláves Ctrl+C zastavte spuštěnou aplikaci.
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í.
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.
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
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.
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í 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ů.
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 Dockeru.
Na panelu DOCKER v části KONTEJNERY klikněte pravým tlačítkem na kontejner produktů 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 vašeho codespace a na kartě TERMINÁL vyberte terminál Dockeru. Strategie odolnosti funguje.
Na panelu DOCKER v části KONTEJNERY klikněte pravým tlačítkem na kontejner produktů a vyberte 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.