Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La resilienza è la capacità di un'app di riprendersi da guasti transitori e continuare a funzionare. Nel contesto della programmazione .NET, la resilienza si ottiene progettando app in grado di gestire i guasti con eleganza e recuperare rapidamente. Per aiutare a costruire app resilienti in .NET, i seguenti due pacchetti sono disponibili su NuGet:
| Pacchetto NuGet | Descrizione |
|---|---|
| 📦 Microsoft.Extensions.Resilience | Questo pacchetto NuGet fornisce meccanismi per proteggere le app contro i guasti transitori. |
| 📦 Microsoft.Extensions.Http.Resilience | Questo pacchetto NuGet fornisce meccanismi di resilienza specifici per la classe HttpClient. |
Questi due pacchetti NuGet sono costruiti sopra Polly, che è un popolare progetto open-source. Polly è una libreria .NET per la resilienza e la gestione dei guasti transitori che permette agli sviluppatori di esprimere strategie come il retry, circuit breaker, timeout, bulkhead isolation, rate-limiting, fallback, e hedging in modo fluente e thread-safe.
Importante
Il pacchetto NuGet Microsoft.Extensions.Http.Polly è deprecato. Usa invece uno dei pacchetti menzionati.
Inizia subito
Per iniziare a utilizzare la resilienza in .NET, installa il pacchetto NuGet Microsoft.Extensions.Resilience.
dotnet add package Microsoft.Extensions.Resilience
Per altre informazioni, vedere dotnet package add or Manage package dependencies in .NET applications (Aggiungere o gestire le dipendenze dei pacchetti nelle applicazioni .NET).
Costruisci una pipeline di resilienza
Per utilizzare la resilienza, è necessario prima costruire un insieme di strategie basate sulla resilienza. Ogni strategia configurata viene eseguita in ordine di configurazione. In altre parole, l'ordine è importante. Il punto di ingresso è un metodo di estensione sul tipo IServiceCollection, chiamato AddResiliencePipeline. Questo metodo prende un identificatore del pipeline e un delegato che configura il pipeline. Al delegato viene passata un'istanza di ResiliencePipelineBuilder, che viene utilizzata per aggiungere strategie di resilienza alla pipeline.
Considera il seguente esempio basato su stringhe:
using Microsoft.Extensions.DependencyInjection;
using Polly;
using Polly.CircuitBreaker;
using Polly.Registry;
using Polly.Retry;
using Polly.Timeout;
var services = new ServiceCollection();
const string key = "Retry-Timeout";
services.AddResiliencePipeline(key, static builder =>
{
// See: https://www.pollydocs.org/strategies/retry.html
builder.AddRetry(new RetryStrategyOptions
{
ShouldHandle = new PredicateBuilder().Handle<TimeoutRejectedException>()
});
// See: https://www.pollydocs.org/strategies/timeout.html
builder.AddTimeout(TimeSpan.FromSeconds(1.5));
});
Il codice precedente:
- Crea una nuova istanza di
ServiceCollection. - Definisce un
keyper identificare la pipeline. - Aggiunge una pipeline di resilienza all'istanza
ServiceCollection. - Configura la pipeline con strategie di ripetizione e timeout.
Ogni pipeline è configurata per un determinato key, e ciascun key viene utilizzato per identificare il suo corrispondente ResiliencePipeline quando si ottiene la pipeline dal fornitore. Il parametro di tipo generico del metodo key è AddResiliencePipeline.
Estensioni del costruttore di pipeline di resilienza
Per aggiungere una strategia alla pipeline, chiama uno dei metodi di estensione disponibili sull'istanza Add*.
-
AddRetry: Riprova se qualcosa fallisce, il che è utile quando il problema è temporaneo e potrebbe scomparire. -
AddCircuitBreaker: Smetti di provare se qualcosa è rotto o occupato, il che ti avvantaggia evitando di perdere tempo e peggiorare le cose. -
AddTimeout: Rinuncia se qualcosa richiede troppo tempo, il che può migliorare le prestazioni liberando risorse. -
AddRateLimiter: Limita il numero di richieste che accetti, il che ti consente di controllare il carico di ingresso. -
AddConcurrencyLimiter: Limita il numero di richieste che fai, consentendoti di controllare il carico in uscita. -
AddFallback: Fai qualcos'altro quando si verificano problemi, il che migliora l'esperienza utente. -
AddHedging: Emetti più richieste in caso di elevata latenza o guasto, il che può migliorare la reattività.
Per ulteriori informazioni, fare riferimento a Resilience strategies. Per esempi, vedere Build resilient HTTP apps: Key development patterns.
Arricchimento delle metriche
Arricchimento è l'augmentazione automatica della telemetria con uno stato ben noto, sotto forma di coppie nome/valore. Ad esempio, un'app potrebbe emettere un registro che include l'operazione e il codice risultato come colonne per rappresentare l'esito di qualche operazione. In questa situazione e a seconda del contesto periferico, l'arricchimento aggiunge Nome del Cluster, Nome del Processo, Regione, ID del Tenente e altro al registro mentre viene inviato al backend di telemetria. Quando viene aggiunto l'arricchimento, il codice dell'app non deve eseguire alcuna operazione aggiuntiva per trarre vantaggio dalle metriche arricchite.
Come funziona l'arricchimento
Si immaginino 1.000 istanze del servizio distribuite a livello globale che generano log e metriche. Quando si verifica un problema nel dashboard del servizio, è fondamentale identificare rapidamente l'area o il data center problematico. L'arricchimento garantisce che i registri metrici contengano le informazioni necessarie per individuare i guasti nei sistemi distribuiti. Senza arricchimento, l'onere ricade sul codice dell'applicazione di gestire internamente questo stato, integrarlo nel processo di registrazione e trasmetterlo manualmente. L'arricchimento semplifica questo processo, gestendolo senza soluzione di continuità senza influenzare la logica dell'app.
In caso di resilienza, quando si aggiunge l'arricchimento, le seguenti dimensioni vengono aggiunte alla telemetria in uscita:
-
error.type: Versione a bassa cardinalità delle informazioni di un'eccezione. -
request.name: Il nome della richiesta. -
request.dependency.name: nome della dipendenza.
Sotto il cofano, l'arricchimento della resilienza è costruito sopra la Telemetria di Polly MeteringEnricher. Per ulteriori informazioni, vedere Polly: Metering enrichment.
Aggiungere l'arricchimento con resilienza
Oltre a registrare un pipeline di resilienza, puoi anche registrare un arricchimento di resilienza. Per aggiungere un arricchimento, chiama il metodo di estensioni AddResilienceEnricher(IServiceCollection) sull'istanza IServiceCollection.
services.AddResilienceEnricher();
Chiamando il AddResilienceEnricher metodo di estensione, si aggiungono dimensioni sopra quelle predefinite incorporate nella libreria Polly sottostante. Le seguenti dimensioni di arricchimento vengono aggiunte:
- Arricchimento delle eccezioni basato su IExceptionSummarizer, che fornisce un meccanismo per riassumere le eccezioni da utilizzare nella telemetria. Per ulteriori informazioni, vedere Riepilogo delle eccezioni.
- Richiedi l'arricchimento dei metadati basato su RequestMetadata, che contiene i metadati della richiesta per la telemetria. Per ulteriori informazioni, consultare Polly: Telemetry metrics.
Utilizzare la pipeline di resilienza
Per usare una pipeline di resilienza configurata, è necessario ottenere la pipeline da un oggetto ResiliencePipelineProvider<TKey>. Quando è stata aggiunta la pipeline in precedenza, key è di tipo string, quindi è necessario ottenere la pipeline da ResiliencePipelineProvider<string>.
using ServiceProvider provider = services.BuildServiceProvider();
ResiliencePipelineProvider<string> pipelineProvider =
provider.GetRequiredService<ResiliencePipelineProvider<string>>();
ResiliencePipeline pipeline = pipelineProvider.GetPipeline(key);
Il codice precedente:
- Costruisce un
ServiceProviderdall'istanza diServiceCollection. - Ottiene l'oggetto
ResiliencePipelineProvider<string>dal provider di servizi. - Recupera l'oggetto
ResiliencePipelinedaResiliencePipelineProvider<string>.
Eseguire la pipeline di resilienza
Per utilizzare il resilience pipeline, chiama uno qualsiasi dei metodi disponibili sull'istanza Execute*. Si consideri ad esempio una chiamata al ExecuteAsync metodo :
await pipeline.ExecuteAsync(static cancellationToken =>
{
// Code that could potentially fail.
return ValueTask.CompletedTask;
});
Il codice precedente esegue il delegate nel metodo ExecuteAsync. Quando si verificano dei guasti, vengono eseguite le strategie configurate. Ad esempio, se RetryStrategy è configurato per riprovare tre volte, il delegato viene eseguito quattro volte (un tentativo iniziale più tre tentativi di ripetizione) prima che l'errore venga propagato.