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 --version 8.0.0
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
key
per 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 AddResiliencePipeline
è key
.
Estensioni del costruttore di pipeline di resilienza
Per aggiungere una strategia alla pipeline, chiama uno dei metodi di estensione disponibili sull'istanza ResiliencePipelineBuilder
.
-
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.
Metrics enrichment
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. When enrichment is added, the app code doesn't need to do anything extra to benefit from enriched metrics.
Come funziona l'arricchimento
Imagine 1,000 globally distributed service instances generating logs and metrics. When you encounter an issue on your service dashboard, it's crucial to quickly identify the problematic region or data center. 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
: The name of the dependency.
Sotto il cofano, l'arricchimento della resilienza è costruito sopra la Telemetria di Polly MeteringEnricher
. Per ulteriori informazioni, vedere Polly: Metering enrichment.
Add resilience enrichment
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();
By calling the AddResilienceEnricher
extension method, you're adding dimensions on top of the default ones that are built into the underlying Polly library. 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.
Use resilience pipeline
To use a configured resilience pipeline, you must get the pipeline from a ResiliencePipelineProvider<TKey>
. When you added the pipeline earlier, the key
was of type string
, so you must get the pipeline from the ResiliencePipelineProvider<string>
.
using ServiceProvider provider = services.BuildServiceProvider();
ResiliencePipelineProvider<string> pipelineProvider =
provider.GetRequiredService<ResiliencePipelineProvider<string>>();
ResiliencePipeline pipeline = pipelineProvider.GetPipeline(key);
Il codice precedente:
- Costruisce un
ServiceProvider
dall'istanza diServiceCollection
. - Gets the
ResiliencePipelineProvider<string>
from the service provider. - Retrieves the
ResiliencePipeline
from theResiliencePipelineProvider<string>
.
Execute resilience pipeline
Per utilizzare il resilience pipeline, chiama uno qualsiasi dei metodi disponibili sull'istanza ResiliencePipeline
. For example, consider an example call to ExecuteAsync
method:
await pipeline.ExecuteAsync(static cancellationToken =>
{
// Code that could potentially fail.
return ValueTask.CompletedTask;
});
The preceding code executes the delegate within the ExecuteAsync
method. Quando si verificano dei guasti, vengono eseguite le strategie configurate. For example, if the RetryStrategy
is configured to retry three times, the delegate is executed four times (one initial attempt plus three retry attempts) before the failure is propagated.