Esercizio - Implementare la resilienza dell'applicazione
Il progetto eShop ha due servizi che comunicano tra loro usando le richieste HTTP. Il Store servizio chiama il Product servizio per ottenere l'elenco di tutti i prodotti correnti disponibili per l'acquisto.
La versione corrente dell'app non ha alcuna gestione della resilienza. Se il Product servizio non è disponibile, il Store servizio restituisce un errore ai clienti e chiede di riprovare più tardi. Questo comportamento non è un'esperienza utente ottimale.
Il responsabile chiede di aggiungere resilienza all'app, in modo che il Store servizio ritenta la chiamata al servizio back-end in caso di errore.
In questo esercizio si aggiunge resilienza a un'app nativa del cloud esistente e si testa la correzione.
Aprire l'ambiente di sviluppo
Si può scegliere di ospitare l'esercizio in un codespace GitHub oppure di completarlo in locale in Visual Studio Code.
Per usare un codespace, crea un codespace GitHub preconfigurato con questo link di creazione Codespace.
GitHub richiede alcuni minuti per creare e configurare lo spazio di codice. Al termine del processo, viene visualizzato il file di codice per l'esercizio. Il codice da usare per il resto di questo modulo si trova nella directory /dotnet-resiliency .
Per usare Visual Studio Code, clonare il repository https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative nel computer locale. Quindi:
- Installare eventuali requisiti di sistema per eseguire il contenitore di sviluppo in Visual Studio Code.
- Verificare che Docker sia in esecuzione.
- In una nuova finestra di Visual Studio Code, aprire la cartella del repository clonato
- Premere CTRL+MAIUSC+P per aprire il riquadro comandi.
- Ricerca: >Contenitori di sviluppo: Ricompilare e riaprire nel contenitore
- Selezionare eShopLite - dotnet-resiliency nell'elenco a discesa. Visual Studio Code crea il contenitore di sviluppo in locale.
Compilare ed eseguire l'app
Nel pannello inferiore selezionare la scheda TERMINALE ed eseguire il comando seguente per passare alla radice del codice:
cd dotnet-resiliencyEseguire il comando seguente per compilare le immagini dell'app eShop:
dotnet publish /p:PublishProfile=DefaultContainerAl termine della compilazione, eseguire il comando seguente per avviare l'app:
docker compose upNel pannello inferiore selezionare la scheda PORTE , quindi nella colonna Indirizzo inoltrato della tabella selezionare l'icona Apri nel browser per la porta Front End (32000).
Se si esegue l'app in locale, aprire una finestra del browser per visualizzare
http://localhost:32000/products.L'app eShop dovrebbe essere in esecuzione. Selezionare la voce di menu Prodotti . Verrà visualizzato l'elenco dei prodotti.
Testare la resilienza corrente
Interrompere il servizio del prodotto per vedere cosa succede all'app.
Tornare allo spazio di codice e nella scheda TERMINALE selezionare + per aprire un nuovo terminale bash.
Eseguire il comando docker seguente per elencare i contenitori in esecuzione:
docker psVerrà visualizzato l'elenco dei contenitori attualmente in esecuzione, ad esempio:
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 minutesCercare l'ID CONTENITORE per il contenitore productservice. Nell'esempio precedente l'ID è 6ba80f3c7ab0.
Arrestare il servizio prodotto con questo comando docker:
docker stop <CONTAINER ID>Dove
<CONTAINER ID>è l'ID che hai trovato nel passaggio precedente. Per esempio:docker stop 6ba80f3c7ab0Tornare alla scheda del browser che esegue l'app e aggiornare la pagina. Verrà visualizzato un messaggio di errore:
C'è un problema durante il caricamento dei nostri prodotti. Riprova più tardi.
Tornare allo spazio di codice e nel terminale selezionare il terminale docker e premere CTRL+C per arrestare l'app. Dovresti vedere:
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
Aggiungere resilienza all'app
I primi passaggi per rendere l'app più resiliente sono aggiungere il Microsoft.Extensions.Http.Resilience pacchetto NuGet al progetto. È quindi possibile usarlo in Program.cs.
Aggiungere il pacchetto Microsoft.Extensions.Http.Resilience
Nello spazio di codice, nella scheda TERMINALE , passare alla cartella del progetto Store :
cd StoreEseguire il comando seguente per aggiungere il pacchetto NuGet con resilienza:
dotnet add package Microsoft.Extensions.Http.ResilienceL'esecuzione di questo comando dal terminale nella cartella del progetto app aggiunge il riferimento al pacchetto al file di progetto Store.csproj .
Nella barra laterale EXPLORER selezionare Program.cs.
All'inizio del file, aggiungere le istruzioni using seguenti:
using Microsoft.Extensions.Http.Resilience;
Aggiungere una strategia di resilienza standard
Alla riga 13, prima di ;, aggiungere questo codice:
.AddStandardResilienceHandler()Il codice dovrebbe essere simile al seguente:
builder.Services.AddHttpClient<ProductService>(c => { var url = builder.Configuration["ProductEndpoint"] ?? throw new InvalidOperationException("ProductEndpoint is not set"); c.BaseAddress = new(url); }).AddStandardResilienceHandler();Il codice precedente aggiunge un gestore di resilienza standard a HTTPClient. Il gestore usa tutte le impostazioni predefinite per la strategia di resilienza standard.
Non sono necessarie altre modifiche al codice per l'app. Eseguire l'app e testare la resilienza.
Eseguire i comandi seguenti per ricompilare l'app eShop:
cd .. dotnet publish /p:PublishProfile=DefaultContainerAl termine della compilazione, eseguire il comando seguente per avviare l'app:
docker compose upTornare alla scheda del browser che esegue l'app e aggiornare la pagina del prodotto. Verrà visualizzato l'elenco dei prodotti.
Tornare allo spazio di codice e nella scheda TERMINALE selezionare il secondo terminale bash. Copiare l'ID CONTENITORE per il contenitore productservice .
Eseguire di nuovo il comando docker stop:
docker stop <CONTAINER ID>Tornare alla scheda del browser che esegue l'app e aggiornare la pagina del prodotto. Questa volta, l'operazione dovrebbe richiedere più tempo fino a quando non viene visualizzato il messaggio di errore delle app:
C'è un problema durante il caricamento dei nostri prodotti. Riprova più tardi.
Controllare i log per verificare se la strategia di resilienza funziona.
Tornare allo spazio di codice e nella scheda TERMINALE selezionare il terminale Docker .
Nel terminale premere CTRL+C per arrestare l'esecuzione dell'app.
Nei messaggi di log scorrere verso l'alto fino a trovare i riferimenti a 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'Dovrebbero essere visualizzati molti messaggi come questo; ognuno di essi è un tentativo di ripetizione. Il messaggio precedente mostra il secondo tentativo e il tempo necessario per l'esecuzione.
Configurare una strategia di resilienza
Quando si aggiunge resilienza all'app, si bilancia la necessità di rispondere rapidamente agli utenti, con la necessità di non eseguire l'overload di alcun servizio back-end. È possibile decidere solo se le opzioni predefinite soddisfano le esigenze aziendali.
In questo esempio si vuole che il servizio del negozio attenda un po' più a lungo, per offrire al servizio del negozio la possibilità di eseguire il ripristino.
Nella finestra del codice per Program.cs modificare il codice alla riga 13 in:
.AddStandardResilienceHandler(options => { options.Retry.MaxRetryAttempts = 7; });Il codice precedente modifica le impostazioni predefinite della strategia di ripetizione dei tentativi in modo da impostare un massimo di sette tentativi. Ricorda che la strategia è un ritardo esponenziale, quindi il tempo totale è di circa 5 minuti.
Arrestare docker con CTRL+C. Eseguire quindi il comando seguente per ricompilare l'app eShop:
dotnet publish /p:PublishProfile=DefaultContainerAl termine della compilazione, eseguire il comando seguente per avviare l'app:
docker compose upArrestare il container del servizio backend nel terminale bash e successivamente aggiornare l'eShop. Si noti che la visualizzazione del messaggio di errore richiede più tempo. Se si controllano però i log, è possibile notare che la strategia di ripetizione dei tentativi è stata ritentata cinque volte. L'ultimo messaggio di Polly è:
Polly.Timeout.TimeoutRejectedException: The operation didn't complete within the allowed timeout of '00:00:30'.Il messaggio precedente indica che il timeout totale per le richieste impedisce il raggiungimento del numero massimo di tentativi. È possibile risolvere il problema aumentando il timeout totale della richiesta.
Nel terminale premere CTRL+C per arrestare l'app.
Nella finestra del codice per Program.cs modificare il codice alla riga 13 in:
.AddStandardResilienceHandler(options => { options.Retry.RetryCount = 7; options.TotalRequestTimeout = new HttpTimeoutStrategyOptions { Timeout = TimeSpan.FromMinutes(5) }; });Il codice precedente modifica il timeout totale della richiesta a 260 secondi, che ora è più lungo della strategia di ripetizione dei tentativi.
Con queste modifiche è necessario avere tempo sufficiente per eseguire l'app, arrestare il servizio prodotto, controllare i log del terminale per i tentativi di ripetizione, aggiornare l'eShop per visualizzare il messaggio di caricamento e infine riavviare il servizio prodotto per visualizzare correttamente l'elenco dei prodotti.
Eseguire il comando seguente per ricompilare l'app eShop:
dotnet publish /p:PublishProfile=DefaultContainerAl termine della compilazione, eseguire il comando seguente per avviare l'app:
docker compose up
Testare le nuove opzioni di resilienza
Per testare l'app nel contenitore, usare l'estensione Docker. L'estensione fornisce un'interfaccia utente grafica per visualizzare e controllare lo stato dei contenitori.
Nel menu a sinistra selezionare l'icona Docker .
Nel pannello DOCKER , in CONTENITORi fare clic con il pulsante destro del mouse sul contenitore dei prodotti e scegliere Arresta.
Tornare alla scheda del browser che esegue l'app e aggiornare la pagina del prodotto. Verrà visualizzato il messaggio Caricamento.
Tornare allo spazio di codice e nella scheda TERMINALE selezionare il terminale Docker . La strategia di resilienza funziona.
Nel pannello DOCKER , in CONTENITORi, fare clic con il pulsante destro del mouse sul contenitore dei prodotti e scegliere Avvia.
Tornare alla scheda del browser che esegue l'app. Attendi e l'app dovrebbe recuperarsi mostrando l'elenco dei prodotti.
Nel terminale arrestare Docker con CTRL+C.
