Compartilhar via


Implementar repetições de chamadas HTTP com retirada exponencial com o HttpClientFactory e as políticas do Polly

Dica

Esse conteúdo é um trecho do eBook, arquitetura de microsserviços do .NET para aplicativos .NET em contêineres, disponível em do .NET Docs ou como um PDF para download gratuito que pode ser lido offline.

miniatura da capa do eBook sobre arquitetura de microsserviços do .NET para aplicativos .NET em contêineres.

A abordagem recomendada para repetições com recuo exponencial é aproveitar bibliotecas .NET mais avançadas, como a biblioteca Polly de software livre.

O Polly é uma biblioteca .NET que fornece resiliência e recursos transitórios de tratamento de falhas. Você pode implementar essas funcionalidades por meio da aplicação de políticas da Polly como repetição, disjuntor, isolamento do bulkhead, tempo limite e fallback. O Polly tem como alvo o .NET Framework 4.x e o .NET Standard 1.0, 1.1 e 2.0 (que dá suporte ao .NET Core e posterior).

As etapas a seguir mostram como você pode usar as repetições HTTP com o Polly integrado ao IHttpClientFactory, o que foi explicado na seção anterior.

Instalar pacotes do .NET

Primeiro, você precisará instalar o Microsoft.Extensions.Http.Polly pacote.

Fazer referência aos pacotes do .NET 8

IHttpClientFactory está disponível desde o .NET Core 2.1, no entanto, recomendamos que você use os pacotes .NET 8 mais recentes do NuGet em seu projeto. Normalmente, você também precisa referenciar o pacote Microsoft.Extensions.Http.Pollyde extensão.

Configurar um cliente com a política Retry da Polly, durante a inicialização do aplicativo

O método AddPolicyHandler() é o que adiciona políticas aos HttpClient objetos que você usará. Nesse caso, ele está adicionando a política do Polly para repetições de HTTP com retirada exponencial.

Para ter uma abordagem mais modular, a Política de Repetição http pode ser definida em um método separado dentro do arquivo Program.cs , conforme mostrado no código a seguir:

static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
        .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,
                                                                    retryAttempt)));
}

Conforme mostrado nas seções anteriores, você precisa definir uma configuração HttpClient de cliente nomeada ou tipada na configuração de aplicativos Program.cs padrão. Agora você adiciona código incremental especificando a política para as repetições Http com retirada exponencial, conforme a seguir:

// Program.cs
builder.Services.AddHttpClient<IBasketService, BasketService>()
        .SetHandlerLifetime(TimeSpan.FromMinutes(5))  //Set lifetime to five minutes
        .AddPolicyHandler(GetRetryPolicy());

Com o Polly, você pode definir uma política de repetição com o número de repetições, a configuração de retrocesso exponencial e as ações a serem executadas quando houver uma exceção HTTP, como registrar o erro no log. Nesse caso, a política é configurada para tentar seis vezes com uma repetição exponencial, começando em dois segundos.

Adicionar uma estratégia de tremulação à política de repetição

Uma política de repetição regular pode afetar o sistema em casos de alta simultaneidade e escalabilidade e sob alta contenção. Para superar os picos de repetições semelhantes provenientes de muitos clientes em caso de interrupções parciais, uma boa solução alternativa é adicionar uma estratégia de variação à política ou ao algoritmo de repetição. Essa estratégia pode melhorar o desempenho geral do sistema de ponta a ponta. Conforme recomendado em Polly: repetição com variação, uma boa estratégia de variação pode ser implementada por intervalos de repetição suaves e distribuídos uniformemente, aplicados com um atraso de repetição inicial mediano bem controlado em uma retirada exponencial. Essa abordagem ajuda a espalhar os picos quando o problema surge. O princípio é ilustrado pelo seguinte exemplo:


var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5);

var retryPolicy = Policy
    .Handle<FooException>()
    .WaitAndRetryAsync(delay);

Recursos adicionais