Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Resiliência é a capacidade de um aplicativo se recuperar de falhas transitórias e continuar funcionando. No contexto da programação do .NET, a resiliência é obtida com a criação de aplicativos que podem lidar com falhas normalmente e se recuperar rapidamente. Para ajudar a criar aplicativos resilientes no .NET, os dois pacotes a seguir estão disponíveis no NuGet:
Pacote NuGet | Descrição |
---|---|
📦 Microsoft.Extensions.Resilience | Esse pacote NuGet fornece mecanismos para proteger aplicativos contra falhas transitórias. |
📦 Microsoft.Extensions.Http.Resilience | Esse pacote NuGet fornece mecanismos de resiliência especificamente para a HttpClient classe. |
Esses dois pacotes NuGet são criados com base no Polly, que é um projeto popular de software livre. Polly é uma biblioteca de resiliência e manipulação de falhas transitórias do .NET que permite que aos desenvolvedores expressarem as estratégias como repetição, circuit breaker, tempo limite, isolamento bulkhead, limitação de taxa, fallback e hedging de forma mais fluente e thread-safe.
Importante
O pacote NuGet Microsoft.Extensions.Http.Polly foi preterido. Em vez disso, use um dos pacotes mencionados acima.
Comece agora
Para começar a usar a resiliência no .NET, instale o pacote NuGet Microsoft.Extensions.Resilience .
dotnet add package Microsoft.Extensions.Resilience --version 8.0.0
Para obter mais informações, consulte dotnet package add ou Gerenciar dependências de pacotes em aplicativos .NET.
Criar um pipeline de resiliência
Para usar a resiliência, primeiro você deve criar um pipeline de estratégias baseadas em resiliência. Cada estratégia configurada é executada em ordem de configuração. Em outras palavras, a ordem é importante. O ponto de entrada é um método de extensão do tipo IServiceCollection, denominado AddResiliencePipeline
. Esse método usa um identificador do pipeline e um delegado que configura o pipeline. O delegado recebe uma instância ResiliencePipelineBuilder
, que é usada com o objetivo de adicionar estratégias de resiliência ao pipeline.
Considere o seguinte exemplo de cadeia de caracteres baseado em key
:
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));
});
O código anterior:
- Cria uma nova instância de
ServiceCollection
. - Define
key
para identificar o pipeline. - Adiciona um pipeline de resiliência à instância
ServiceCollection
. - Configura o pipeline com estratégias de repetição e tempo limite.
Cada pipeline é configurado para um determinado key
, e cada key
é usado para identificar seu respectivo ResiliencePipeline
correspondente ao obter o pipeline do provedor. É key
um parâmetro de tipo genérico do AddResiliencePipeline
método.
Extensões do construtor de pipeline de resiliência
Para adicionar uma estratégia ao pipeline, chame qualquer um dos métodos de extensão Add*
disponíveis na instância ResiliencePipelineBuilder
.
-
AddRetry
: tente novamente se algo falhar, o que é útil quando o problema é temporário e pode desaparecer. -
AddCircuitBreaker
: pare de tentar se algo está quebrado ou ocupado, o que beneficia você evitando o tempo perdido e piorando as coisas. -
AddTimeout
: desista se algo demorar muito, para melhorar o desempenho ao liberar recursos. -
AddRateLimiter
: limite quantas solicitações você aceita, o que permite controlar a carga de entrada. -
AddConcurrencyLimiter
: limite quantas solicitações você faz, o que permite controlar a carga de saída. -
AddFallback
: faça outra coisa ao sofrer falhas, o que melhora a experiência do usuário. -
AddHedging
: emita várias solicitações em caso de alta latência ou falha, o que pode melhorar a capacidade de resposta.
Para obter mais informações, consulte estratégias de resiliência. Para obter exemplos, consulte Criar aplicativos HTTP resilientes: principais padrões de desenvolvimento.
Enriquecimento de métricas
Enriquecimento é o acréscimo automático da telemetria com o estado bem-conhecido, na forma de pares nome/valor. Por exemplo, um aplicativo pode emitir um log que inclui a operação e o código de resultado como colunas para representar o resultado de alguma operação. Nessa situação e dependendo do contexto periférico, o enriquecimento adiciona o nome do cluster, o nome do processo, a região, a ID do locatário e muito mais ao log conforme ele é enviado para o back-end de telemetria. Quando o enriquecimento é adicionado, o código do aplicativo não precisa fazer nada extra para se beneficiar de métricas enriquecidas.
Como funciona o enriquecimento
Imagine 1.000 instâncias de serviço distribuídas globalmente gerando logs e métricas. Quando você encontra um problema no painel de serviço, é crucial identificar rapidamente a região problemática ou o data center. O enriquecimento garante que os registros de métrica contenham as informações necessárias para identificar falhas em sistemas distribuídos. Sem enriquecimento, a carga recai sobre o código do aplicativo para gerenciar internamente esse estado, integrá-lo ao processo de registro em log e transmiti-lo manualmente. O enriquecimento simplifica esse processo, tratando-o perfeitamente sem afetar a lógica do aplicativo.
No caso de resiliência, quando você adiciona enriquecimento, as seguintes dimensões são adicionadas à telemetria de saída:
-
error.type
: versão de baixa cardinalidade das informações de uma exceção. -
request.name
: o nome da solicitação. -
request.dependency.name
: o nome da propriedade de dependência.
Nos bastidores, o enriquecimento da resiliência é criado de acordo com a Telemetria MeteringEnricher
de Polly. Para obter mais informações, consulte Polly: enriquecimento da medição.
Adicionar enriquecimento de resiliência
Além de registrar um pipeline de resiliência, você também pode registrar o enriquecimento de resiliência. Para adicionar enriquecimento, chame o AddResilienceEnricher(IServiceCollection) método de extensões na IServiceCollection
instância.
services.AddResilienceEnricher();
Ao chamar o método de extensão AddResilienceEnricher
, você está adicionando dimensões além das que são padrão e incorporadas à biblioteca Polly subjacente. As seguintes dimensões de enriquecimento são adicionadas:
- Enriquecimento de exceção com base no IExceptionSummarizer, que fornece um mecanismo para resumir exceções para uso na telemetria. Para obter mais informações, consulte Resumo de exceção.
- Solicite o enriquecimento de metadados com base em RequestMetadata, que contém os metadados de solicitação para telemetria. Para obter mais informações, consulte Polly: Métricas de telemetria.
Usar o pipeline de resiliência
Para usar um pipeline de resiliência configurado, você deve obter o pipeline de ResiliencePipelineProvider<TKey>
. Quando você adicionou o pipeline anteriormente, key
era do tipo string
; portanto, você deve obter o pipeline direto de ResiliencePipelineProvider<string>
.
using ServiceProvider provider = services.BuildServiceProvider();
ResiliencePipelineProvider<string> pipelineProvider =
provider.GetRequiredService<ResiliencePipelineProvider<string>>();
ResiliencePipeline pipeline = pipelineProvider.GetPipeline(key);
O código anterior:
- Cria uma instância
ServiceProvider
a partir deServiceCollection
. - Obtém
ResiliencePipelineProvider<string>
do provedor de serviços. - Recupera o
ResiliencePipeline
deResiliencePipelineProvider<string>
.
Executar o pipeline de resiliência
Para usar o pipeline de resiliência, chame qualquer um dos métodos Execute*
disponíveis na instância ResiliencePipeline
. Por exemplo, considere um exemplo de chamada ao ExecuteAsync
método:
await pipeline.ExecuteAsync(static cancellationToken =>
{
// Code that could potentially fail.
return ValueTask.CompletedTask;
});
O código anterior executa o delegado dentro do ExecuteAsync
método. Quando há falhas, as estratégias configuradas são executadas. Por exemplo, se RetryStrategy
estiver configurado para tentar novamente três vezes, o delegado será executado quatro vezes (uma tentativa inicial mais três tentativas de repetição) antes que a falha seja propagada.