La resilienza è la capacità di un'app di eseguire il ripristino da errori temporanei e continuare a funzionare. Nel contesto della programmazione .NET, la resilienza viene ottenuta progettando app in grado di gestire correttamente gli errori e ripristinarsi rapidamente. Per creare app resilienti in .NET, in NuGet sono disponibili i due pacchetti seguenti:
Questo pacchetto NuGet fornisce meccanismi di resilienza specifici per la classe HttpClient.
Questi due pacchetti NuGet sono basati su Polly, un progetto open source molto diffuso. Polly è una libreria di resilienza .NET e di gestione degli errori temporanei che consente agli sviluppatori di esprimere strategie come retry, interruttore, timeout, isolamento bulkhead, limite di frequenza, fallback e hedging in modo fluente e thread-safe.
Per usare la resilienza, è prima necessario creare una pipeline 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, denominato AddResiliencePipeline. Questo metodo accetta un identificatore della pipeline e un delegato che configura la pipeline. Il delegato viene passato a un'istanza di ResiliencePipelineBuilder, che viene usata per aggiungere strategie di resilienza alla pipeline.
Si consideri l'esempio basato su stringa seguente key:
C#
using Microsoft.Extensions.DependencyInjection;
using Polly;
using Polly.CircuitBreaker;
using Polly.Registry;
using Polly.Retry;
using Polly.Timeout;
var services = new ServiceCollection();
conststring 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 key per identificare la pipeline.
Aggiunge una pipeline di resilienza all'istanza ServiceCollection.
Configura la pipeline con strategie di retry e timeout.
Ogni pipeline è configurata per un determinato key e ogni key viene usato per identificare il corrispondente ResiliencePipeline, quando si ottiene la pipeline dal provider. key è un parametro di tipo generico del metodo AddResiliencePipeline.
Estensioni del generatore di pipeline con resilienza
Per aggiungere una strategia alla pipeline, chiamare uno dei metodi di estensione disponibili Add* nell'istanza ResiliencePipelineBuilder.
AddRetry: riprovare se si verifica un errore, utile quando il problema è temporaneo e potrebbe risolversi
AddCircuitBreaker: interrompere i tentativi se qualcosa è rotto o occupato, il che avvantaggia l'utente, evitando di perdere tempo e di peggiorare le cose.
AddTimeout: rinunciare se un elemento richiede troppo tempo, il che può migliorare le prestazioni liberando le risorse.
AddRateLimiter: limitare il numero di richieste accettate, il che consente di controllare il carico in ingresso.
AddConcurrencyLimiter: limitare il numero di richieste effettuate, il che consente di controllare il carico in uscita.
AddFallback: eseguire altre operazioni quando si verificano errori, migliorando l'esperienza utente.
AddHedging: eseguire più richieste in caso di elevata latenza o errore, il che può migliorare la velocità di risposta.
L'arricchimento è l'aumento automatico dei dati di telemetria con stato noto, sotto forma di coppie nome/valore. Ad esempio, un'app potrebbe generare un log che include l'operazione e il codice del risultato come colonne per rappresentare il risultato di un'operazione. In questa situazione e a seconda del contesto periferico, l'arricchimento aggiunge al registro il nome del cluster, il nome del processo, l'area geografica, l'ID tenant e altro, man mano che viene inviato al back-end di telemetria. Quando viene aggiunto l'arricchimento, il codice dell'app non deve eseguire alcuna operazione aggiuntiva per trarre vantaggio dalle metriche arricchite.
Funzionamento dell'arricchimento
Poniamo 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 record delle metriche contengano le informazioni necessarie per individuare gli errori nei sistemi distribuiti. Senza arricchimento, il carico di lavoro dipende dal codice dell'app per gestire internamente questo stato, integrarlo nel processo di registrazione e trasmetterlo manualmente. L'arricchimento semplifica questo processo, gestendolo senza influire sulla logica dell'app.
In caso di resilienza, quando si aggiunge l'arricchimento, le dimensioni seguenti vengono aggiunte ai dati di telemetria in uscita:
error.type: versione a cardinalità bassa delle informazioni di un'eccezione.
request.name: il nome della richiesta.
request.dependency.name: il nome della dipendenza.
Dietro le quinte, l'arricchimento della resilienza si basa sulla telemetria di Polly MeteringEnricher. Per altre informazioni, vedere Polly: Misurazione dell'arricchimento.
Aggiungere l'arricchimento con resilienza
Oltre a registrare una pipeline di resilienza, è anche possibile registrare l'arricchimento con resilienza. Per aggiungere l'arricchimento, chiamare il metodo extensions AddResilienceEnricher(IServiceCollection) nell'istanza IServiceCollection.
C#
services.AddResilienceEnricher();
Chiamando il metodo di estensione AddResilienceEnricher, si aggiungono dimensioni sopra quelle predefinite incorporate nella libreria Polly sottostante. Vengono aggiunte le dimensioni di arricchimento seguenti:
Arricchimento delle eccezioni basato su IExceptionSummarizer, che fornisce un meccanismo per riepilogare le eccezioni da usare nella telemetria. Per altre informazioni, vedere Riepilogo delle eccezioni.
Richiedere l'arricchimento dei metadati in base a RequestMetadata, che contiene i metadati della richiesta per la telemetria. Per altre informazioni, vedere Polly: metriche di telemetria.
Usare 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 era di tipo string, quindi è necessario ottenere la pipeline da ResiliencePipelineProvider<string>.
Compila un oggetto ServiceProvider dall'istanza ServiceCollection.
Ottiene l'oggetto ResiliencePipelineProvider<string> dal provider di servizi.
Recupera l'oggetto ResiliencePipeline da ResiliencePipelineProvider<string>.
Eseguire la pipeline di resilienza
Per usare la pipeline di resilienza, chiamare uno dei metodi disponibili Execute* nell'istanza ResiliencePipeline. Si consideri ad esempio una chiamata al metodo ExecuteAsync:
C#
await pipeline.ExecuteAsync(static cancellationToken =>
{
// Code that could potentially fail.return ValueTask.CompletedTask;
});
Il codice precedente esegue il delegato all'interno del metodo ExecuteAsync. In caso di errori, 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), prima della propagazione dell'errore.
L'origine per questo contenuto è disponibile in GitHub, dove puoi anche creare ed esaminare i problemi e le richieste pull. Per altre informazioni, vedi la nostra guida per i collaboratori.
Feedback su .NET
.NET è un progetto open source. Seleziona un collegamento per fornire feedback: