Diretrizes de repetição para serviços do Azure

A maioria dos serviços do Azure e dos SDKs do cliente incluem um mecanismo de repetição. No entanto, estes diferem uma vez que cada serviço tem características e requisitos diferentes e, por isso, cada mecanismo de repetição é otimizado para um serviço específico. Este guia resume os recursos do mecanismo de repetição para a maioria dos serviços do Azure e inclui informações para ajudá-lo a usar, adaptar ou estender o mecanismo de repetição para esse serviço.

Para obter orientações gerais sobre o processamento de falhas transitórias e a repetição de ligações, assim como operações referentes a serviços e recursos, veja Orientações do mecanismo de repetição.

A tabela seguinte resume as funcionalidades de repetição dos serviços do Azure descritas nestas orientações.

Serviço Capacidades de repetição Configuração da política Scope Funcionalidades de telemetria
Microsoft Entra ID Nativo na biblioteca MSAL Incorporado na biblioteca MSAL Interna Nenhuma
BD do Cosmos para o Azure Nativo no serviço Não configurável Global TraceSource
Arquivo do Data Lake Nativo no cliente Não configurável Operações individuais Nenhuma
Hubs de Eventos Nativo no cliente Programática Cliente Nenhuma
Hub IoT Nativo no SDK do cliente Programática Cliente Nenhuma
Cache do Azure para Redis Nativo no cliente Programática Cliente TextWriter
Procurar Nativo no cliente Programática Cliente ETW ou personalizada
Service Bus Nativo no cliente Programática Gestor de Espaço de Nome, Fábrica de Mensagens e Cliente ETW
Service Fabric Nativo no cliente Programática Cliente Nenhuma
Base de Dados SQL com ADO.NET Polly Declarativa e programática Instruções únicas ou blocos de código Personalizado
Base de Dados SQL com o Entity Framework Nativo no cliente Programática Global por AppDomain Nenhuma
Base de Dados SQL com o Entity Framework Core Nativo no cliente Programática Global por AppDomain Nenhuma
Armazenamento Nativo no cliente Programática Operações individuais e do cliente TraceSource

Nota

Para a maioria dos mecanismos de repetição internos do Azure, atualmente não há como aplicar uma política de repetição diferente para diferentes tipos de erro ou exceção. Você deve configurar uma política que forneça o melhor desempenho médio e disponibilidade. Uma forma de otimizar a política consiste em analisar os ficheiros de registo para determinar o tipo de falhas transitórias que estão a ocorrer.

Microsoft Entra ID

O Microsoft Entra ID é uma solução abrangente de nuvem de gerenciamento de identidade e acesso que combina serviços de diretório principais, governança avançada de identidade, segurança e gerenciamento de acesso a aplicativos. O Microsoft Entra ID também oferece aos desenvolvedores uma plataforma de gerenciamento de identidade para fornecer controle de acesso aos seus aplicativos, com base em políticas e regras centralizadas.

Nota

Para obter orientação de repetição sobre pontos de extremidade de Identidade de Serviço Gerenciado, consulte Como usar uma Identidade de Serviço Gerenciado de VM do Azure (MSI) para aquisição de token.

Mecanismo de repetição

Há um mecanismo de repetição interno para o Microsoft Entra ID na Biblioteca de Autenticação da Microsoft (MSAL). Para evitar bloqueios inesperados, recomendamos que as bibliotecas de terceiros e o código do aplicativo não tentem novamente conexões com falha, mas permitam que o MSAL manipule as tentativas.

Orientações sobre a utilização da repetição

Considere as seguintes diretrizes ao usar o Microsoft Entra ID:

  • Sempre que possível, use a biblioteca MSAL e o suporte interno para tentativas.
  • Se você estiver usando a API REST para Microsoft Entra ID, tente novamente a operação se o código de resultado for 429 (Muitas solicitações) ou um erro no intervalo 5xx. Não tente novamente se houver outros erros.
  • Para erros 429, tente novamente somente após o tempo indicado no cabeçalho Retry-After .
  • Para erros 5xx, use back-off exponencial, com a primeira tentativa pelo menos 5 segundos após a resposta.
  • Não tente novamente em erros que não sejam 429 e 5xx.

Próximos passos

Azure Cosmos DB

O Azure Cosmos DB é um banco de dados multimodelo totalmente gerenciado que dá suporte a dados JSON sem esquema. Oferece um desempenho configurável e fiável, processamento transacional de JavaScript nativo e é criado para a cloud com dimensionamento flexível.

Mecanismo de repetição

Os SDKs do Azure Cosmos DB tentam novamente automaticamente em determinadas condições de erro, e os aplicativos de usuário são incentivados a ter suas próprias políticas de repetição. Consulte o guia para projetar aplicativos resilientes com SDKs do Azure Cosmos DB para obter uma lista completa de condições de erro e quando tentar novamente.

Telemetria

Dependendo do idioma do seu aplicativo, o diagnóstico e a telemetria são expostos como logs ou propriedades promovidas nas respostas da operação. Para obter mais informações, consulte a seção "Capturar o diagnóstico" no Azure Cosmos DB C# SDK e Azure Cosmos DB Java SDK.

Data Lake Storage

O Data Lake Storage Gen2 torna o Armazenamento do Azure a base para a criação de data lakes corporativos no Azure. O Data Lake Storage Gen2 permite que você gerencie facilmente grandes quantidades de dados.

A biblioteca de cliente Data Lake dos Arquivos de Armazenamento do Azure inclui todos os recursos necessários para tornar mais fácil para desenvolvedores, cientistas de dados e analistas armazenar dados de qualquer tamanho, forma e velocidade, além de fazer todos os tipos de processamento e análise entre plataformas e idiomas.

Mecanismo de repetição

O DataLakeServiceClient permite manipular os recursos e sistemas de arquivos do serviço Azure Data Lake. A conta de armazenamento fornece o namespace de nível superior para o serviço Data Lake. Ao criar o cliente, você pode fornecer as opções de configuração do cliente para se conectar ao serviço Azure Data Lake (DataLakeClientOptions). O DataLakeClientOptions inclui uma propriedade Retry (herdada de Azure.Core.ClientOptions) que pode ser configurada (classe RetryOptions).

Telemetria

Monitorar o uso e o desempenho do Armazenamento do Azure é uma parte importante da operacionalização do seu serviço. Os exemplos incluem operações frequentes, operações com alta latência ou operações que causam limitação do lado do serviço.

Toda a telemetria da sua conta de armazenamento está disponível através dos registos de Armazenamento do Azure no Azure Monitor. Esse recurso integra sua conta de armazenamento com o Log Analytics e Hubs de Eventos, além de permitir que você arquive logs em outra conta de armazenamento. Para ver a lista completa de logs de métricas e recursos e seu esquema associado, consulte Referência de dados de monitoramento do Armazenamento do Azure.

Hubs de Eventos

Os Hubs de Eventos do Azure são um serviço de ingestão de telemetria de hiperescala que coleta, transforma e armazena milhões de eventos.

Mecanismo de repetição

O comportamento de repetição na Biblioteca de Cliente dos Hubs de Eventos do Azure é controlado pela propriedade RetryPolicy na classe EventHubClient. A política padrão tenta novamente com recuo exponencial quando os Hubs de Eventos do Azure retornam um transitório EventHubsException ou um OperationCanceledExceptionarquivo . A política de repetição padrão para Hubs de Eventos é tentar novamente até 9 vezes com um tempo de back-off exponencial de até 30 segundos.

Exemplo

EventHubClient client = EventHubClient.CreateFromConnectionString("[event_hub_connection_string]");
client.RetryPolicy = RetryPolicy.Default;

Próximos passos

Biblioteca de cliente dos Hubs de Eventos do Azure para .NET

Hub IoT

O Hub IoT do Azure é um serviço para conectar, monitorar e gerenciar dispositivos para desenvolver aplicativos de Internet das Coisas (IoT).

Mecanismo de repetição

O SDK do dispositivo IoT do Azure pode detetar erros na rede, no protocolo ou no aplicativo. Com base no tipo de erro, o SDK verifica se uma nova tentativa precisa ser executada. Se o erro for recuperável, o SDK começará a tentar novamente usando a política de repetição configurada.

A política de repetição padrão é um back-off exponencial com desvios aleatórios, mas pode ser configurada.

Configuração da política

A configuração da política difere de acordo com o idioma. Para obter mais informações, consulte Configuração de política de repetição do Hub IoT.

Próximos passos

Cache do Azure para Redis

O Cache Redis do Azure é um serviço de cache de acesso rápido a dados e baixa latência baseado no popular cache Redis de código aberto. É seguro, gerido pela Microsoft e pode ser acedido a partir de qualquer aplicação no Azure.

As orientações nesta secção baseiam-se na utilização do cliente StackExchange.Redis para aceder à cache. Uma lista de outros clientes adequados pode ser encontrada no Site do Redis e estes podem ter mecanismos de repetição diferentes.

O cliente StackExchange.Redis usa multiplexação através de uma única conexão. A utilização recomendada consiste em criar uma instância do cliente durante o arranque da aplicação e utilizar esta instância para todas as operações na cache. Por este motivo, a ligação à cache é realizada apenas uma vez e, por isso, todas as orientações nesta secção estão relacionadas com a política de repetição para esta ligação inicial (e não para cada operação que acede à cache).

Mecanismo de repetição

O cliente StackExchange.Redis usa uma classe de gerenciador de conexões que é configurada por meio de um conjunto de opções, incluindo:

  • ConnectRetry. O número de vezes que uma falha de ligação à cache será repetida.
  • ReconnectRetryPolicy. A estratégia de repetição a utilizar.
  • ConnectTimeout. O tempo de espera máximo em milissegundos.

Configuração da política

As políticas de repetição são configuradas através de programação ao definir as opções para o cliente antes de ligar à cache. Tal pode ser feito através da criação de uma instância da classe ConfigurationOptions, o preenchimento das suas propriedades e a transmissão desta para o método Connect.

As classes incorporadas suportam um atraso linear (constante) e um término exponencial com intervalos de repetição aleatórios. Também pode criar uma política de repetição personalizada ao implementar a interface IReconnectRetryPolicy.

O exemplo a seguir configura uma estratégia de repetição com término exponencial.

var deltaBackOffInMilliseconds = TimeSpan.FromSeconds(5).TotalMilliseconds;
var maxDeltaBackOffInMilliseconds = TimeSpan.FromSeconds(20).TotalMilliseconds;
var options = new ConfigurationOptions
{
    EndPoints = {"localhost"},
    ConnectRetry = 3,
    ReconnectRetryPolicy = new ExponentialRetry(deltaBackOffInMilliseconds, maxDeltaBackOffInMilliseconds),
    ConnectTimeout = 2000
};
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

Em alternativa, pode especificar as opções como uma cadeia e transmiti-la ao método Connect. A propriedade ReconnectRetryPolicy não pode ser definida dessa forma, somente por meio de código.

var options = "localhost,connectRetry=3,connectTimeout=2000";
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

Também pode especificar opções diretamente ao ligar à cache.

var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");

Para obter mais informações, veja Stack Exchange Redis Configuration (Configuração do Stack Exchange Redis) na documentação do StackExchange.Redis.

A tabela seguinte mostra as predefinições da política de repetição incorporada.

Contexto Definição Valor predefinido
(v 1.2.2)
Significado
ConfigurationOptions ConnectRetry

ConnectTimeout

SyncTimeout

ReconnectRetryPolicy
3

Máximo de 5000 ms mais SyncTimeout
1000

LinearRetry de 5000 ms
O número de vezes para repetir tentativas de ligação durante a operação de ligação inicial.
Tempo limite (ms) para operações de ligação. Sem atraso entre as tentativas de repetição.
Tempo (ms) para permitir operações síncronas.

Repetição a cada 5000 ms.

Nota

Para operações síncronas, SyncTimeout pode adicionar a latência de ponto a ponto, porém, a definição demasiado baixa do valor pode provocar tempos limite excessivos. Consulte Como solucionar problemas do Cache do Azure para Redis. Em geral, evitar utilizar operações síncronas e, em alternativa, utilize operações assíncronas. Para obter mais informações, consulte Pipelines e multiplexadores.

Orientações sobre a utilização da repetição

Considere as seguintes diretrizes ao usar o Cache do Azure para Redis:

  • O cliente StackExchange Redis gere as suas próprias repetições, mas apenas ao estabelecer uma ligação à cache quando a aplicação é iniciada pela primeira vez. Você pode configurar o tempo limite de conexão, o número de tentativas de repetição e o tempo entre novas tentativas para estabelecer essa conexão, mas a política de repetição não se aplica a operações no cache.
  • Ao invés de utilizar um grande número de tentativas de repetição, considere reverter ao aceder antes à origem de dados original.

Telemetria

Pode recolher informações sobre ligações (mas não sobre outras operações) com um TextWriter.

var writer = new StringWriter();
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

Um exemplo do resultado gerado é mostrado abaixo.

localhost:6379,connectTimeout=2000,connectRetry=3
1 unique nodes specified
Requesting tie-break from localhost:6379 > __Booksleeve_TieBreak...
Allowing endpoints 00:00:02 to respond...
localhost:6379 faulted: SocketFailure on PING
localhost:6379 failed to nominate (Faulted)
> UnableToResolvePhysicalConnection on GET
No masters detected
localhost:6379: Standalone v2.0.0, master; keep-alive: 00:01:00; int: Connecting; sub: Connecting; not in use: DidNotRespond
localhost:6379: int ops=0, qu=0, qs=0, qc=1, wr=0, sync=1, socks=2; sub ops=0, qu=0, qs=0, qc=0, wr=0, socks=2
Circular op-count snapshot; int: 0 (0.00 ops/s; spans 10s); sub: 0 (0.00 ops/s; spans 10s)
Sync timeouts: 0; fire and forget: 0; last heartbeat: -1s ago
resetting failing connections to retry...
retrying; attempts left: 2...
...

Exemplos

O exemplo de código seguinte configura um atraso constante (linear) entre repetições ao inicializar o cliente StackExchange.Redis. Este exemplo mostra como definir a configuração com uma instância ConfigurationOptions.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace RetryCodeSamples
{
    class CacheRedisCodeSamples
    {
        public async static Task Samples()
        {
            var writer = new StringWriter();
            {
                try
                {
                    var retryTimeInMilliseconds = TimeSpan.FromSeconds(4).TotalMilliseconds; // delay between retries

                    // Using object-based configuration.
                    var options = new ConfigurationOptions
                                        {
                                            EndPoints = { "localhost" },
                                            ConnectRetry = 3,
                                            ReconnectRetryPolicy = new LinearRetry(retryTimeInMilliseconds)
                                        };
                    ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

                    // Store a reference to the multiplexer for use in the application.
                }
                catch
                {
                    Console.WriteLine(writer.ToString());
                    throw;
                }
            }
        }
    }
}

O exemplo seguinte define a configuração ao especificar as opções como uma cadeia. O tempo limite da ligação é o período máximo de tempo para aguardar por uma ligação à cache, não o atraso entre tentativas de repetição. A propriedade ReconnectRetryPolicy só pode ser definida por código.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace RetryCodeSamples
{
    class CacheRedisCodeSamples
    {
        public async static Task Samples()
        {
            var writer = new StringWriter();
            {
                try
                {
                    // Using string-based configuration.
                    var options = "localhost,connectRetry=3,connectTimeout=2000";
                    ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(options, writer);

                    // Store a reference to the multiplexer for use in the application.
                }
                catch
                {
                    Console.WriteLine(writer.ToString());
                    throw;
                }
            }
        }
    }
}

Para obter mais exemplos, veja Configuração no site do projeto.

Próximos passos

O Azure Search pode ser utilizado para adicionar capacidades de pesquisa potentes e sofisticadas para um site ou uma aplicação, resultados de pesquisa otimizados de forma rápida e fácil e construir modelos de classificação otimizado e ricos.

Mecanismo de repetição

O SDK do Azure para .NET inclui uma biblioteca de cliente Azure.Search.Documents da equipe do SDK do Azure que é funcionalmente equivalente à biblioteca de cliente anterior, Microsoft.Azure.Search.

O comportamento de repetição em Microsoft.Azure.Search é controlado pelo método SetRetryPolicy nas classes SearchServiceClient e SearchIndexClient. A política predefinida é repetida com um término exponencial quando o Azure Search devolve uma resposta 5xx ou 408 (Tempo Limite do Pedido).

O comportamento de repetição em Azure.Search.Documents é controlado por SearchClientOptions (faz parte do construtor SearchClient) na propriedade Retry, que pertence à classe Azure.Core.RetryOptions(onde todas as configurações estão disponíveis).

Telemetria

Utilize o ETW para controlar ou registar um fornecedor de rastreio personalizado. Para obter mais informações, veja a Documentação do AutoRest.

Service Bus

O Service Bus é uma plataforma de mensagens na cloud que fornece a troca de mensagens vagamente conjugadas com um dimensionamento e uma resiliência melhorados para os componentes de uma aplicação, esteja alojada na cloud ou no local.

Mecanismo de repetição

O namespace e alguns dos detalhes de configuração dependem de qual pacote SDK do cliente do Service Bus é usado:

Pacote Description Espaço de Nomes
Azure.Messaging.ServiceBus Biblioteca de cliente do Azure Service Bus para .NET Azure.Messaging.ServiceBus
WindowsAzure.ServiceBus Este pacote é a biblioteca de cliente mais antiga do Service Bus. Requer o .NET Framework 4.5.2. Microsoft.Azure.ServiceBus

Orientações sobre a utilização da repetição

A ServiceBusRetryOptions propriedade especifica as opções de repetição para o ServiceBusClient objeto:

Definição Default value Significado
CustomRetryPolicy Uma política de repetição personalizada a ser usada no lugar dos valores de opção individuais.
Atraso 0,8 segundos O atraso entre as tentativas de repetição de uma abordagem fixa ou o atraso no qual basear os cálculos para uma abordagem baseada em backoff.
MaxDelay 60 segundos O atraso máximo permitido entre as tentativas de repetição.
MaxRetries 3 O número máximo de tentativas de repetição antes de considerar que a operação associada falhou.
Modo Exponencial A abordagem a ser usada para calcular atrasos de repetição.
TryTimeout 60 segundos A duração máxima para aguardar a conclusão de uma única tentativa, seja a tentativa inicial ou uma nova tentativa.

Defina a Mode propriedade para configurar o ServiceBusRetryMode com qualquer um destes valores:

Property valor Description
Exponencial 1 As tentativas de repetição serão atrasadas com base em uma estratégia de backoff, onde cada tentativa aumentará a duração que espera antes de tentar novamente.
Fixo 0 As tentativas de repetição acontecem em intervalos fixos; cada atraso tem uma duração consistente.

Exemplo:

using Azure.Messaging.ServiceBus;

string connectionString = "<connection_string>";
string queueName = "<queue_name>";

// Because ServiceBusClient implements IAsyncDisposable, we'll create it
// with "await using" so that it is automatically disposed for us.
var options = new ServiceBusClientOptions();
options.RetryOptions = new ServiceBusRetryOptions
{
    Delay = TimeSpan.FromSeconds(10),
    MaxDelay = TimeSpan.FromSeconds(30),
    Mode = ServiceBusRetryMode.Exponential,
    MaxRetries = 3,
};
await using var client = new ServiceBusClient(connectionString, options);

Telemetria

O Barramento de Serviço coleta os mesmos tipos de dados de monitoramento que outros recursos do Azure. Você pode monitorar o Barramento de Serviço do Azure usando o Azure Monitor.

Você também tem várias opções para enviar telemetria com as bibliotecas de cliente .NET do Service Bus.

Exemplo

O exemplo de código a seguir mostra como usar o Azure.Messaging.ServiceBus pacote para:

  • Defina a política de repetição para um ServiceBusClient usando um novo ServiceBusClientOptions.
  • Crie uma nova mensagem com uma nova instância de um ServiceBusMessagearquivo .
  • Envie uma mensagem para o Service Bus usando o ServiceBusSender.SendMessageAsync(message) método.
  • Receba usando o ServiceBusReceiver, que são representados como ServiceBusReceivedMessage objetos.
// using Azure.Messaging.ServiceBus;

using Azure.Messaging.ServiceBus;

string connectionString = "<connection_string>";
string queueName = "queue1";

// Because ServiceBusClient implements IAsyncDisposable, we'll create it 
// with "await using" so that it is automatically disposed for us.
var options = new ServiceBusClientOptions();
options.RetryOptions = new ServiceBusRetryOptions
{
    Delay = TimeSpan.FromSeconds(10),
    MaxDelay = TimeSpan.FromSeconds(30),
    Mode = ServiceBusRetryMode.Exponential,
    MaxRetries = 3,
};
await using var client = new ServiceBusClient(connectionString, options);

// The sender is responsible for publishing messages to the queue.
ServiceBusSender sender = client.CreateSender(queueName);
ServiceBusMessage message = new ServiceBusMessage("Hello world!");

await sender.SendMessageAsync(message);

// The receiver is responsible for reading messages from the queue.
ServiceBusReceiver receiver = client.CreateReceiver(queueName);
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

string body = receivedMessage.Body.ToString();
Console.WriteLine(body);

Próximos passos

Service Fabric

A distribuição de serviços fiáveis num cluster do Service Fabric protege contra a maioria das potenciais falhas transitórias abordadas neste artigo. Porém, algumas falhas transitórias são ainda possíveis. Por exemplo, o serviço de nomenclatura pode estar no meio de uma alteração de encaminhamento quando obtém um pedido, o que leva à criação de uma exceção. Se o mesmo pedido chegar 100 milissegundos mais tarde, provavelmente será bem-sucedido.

Internamente, o Service Fabric gere este tipo de falhas transitórias. Pode configurar algumas definições com a classe OperationRetrySettings ao configurar os serviços. O código seguinte mostra um exemplo. Na maioria dos casos, isso não deve ser necessário, e as configurações padrão serão boas.

FabricTransportRemotingSettings transportSettings = new FabricTransportRemotingSettings
{
    OperationTimeout = TimeSpan.FromSeconds(30)
};

var retrySettings = new OperationRetrySettings(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(1), 5);

var clientFactory = new FabricTransportServiceRemotingClientFactory(transportSettings);

var serviceProxyFactory = new ServiceProxyFactory((c) => clientFactory, retrySettings);

var client = serviceProxyFactory.CreateServiceProxy<ISomeService>(
    new Uri("fabric:/SomeApp/SomeStatefulReliableService"),
    new ServicePartitionKey(0));

Próximos passos

Banco de dados SQL usando ADO.NET

A Base de Dados SQL é uma base de dados SQL alojada disponível num intervalo de tamanhos e como um serviço standard (partilhado) e premium (não partilhado).

Mecanismo de repetição

A Base de Dados SQL não possui suporte incorporado para repetições quando acedida com o ADO.NET. No entanto, os códigos de retorno dos pedidos podem ser utilizados para determinar o motivo da falha de um pedido. Para obter mais informações sobre a limitação da Base de Dados SQL, veja Limites de recursos da Base de Dados SQL do Azure. Para obter uma lista de códigos de erro relevantes, veja Códigos de erro SQL para aplicações cliente da Base de Dados SQL.

Pode utilizar a biblioteca do Polly para implementar repetições na Base de Dados SQL. Veja Processamento de falhas transitórias com o Polly.

Orientações sobre a utilização da repetição

Considere as seguintes diretrizes ao aceder à Base de Dados SQL com o ADO.NET:

  • Escolha a opção de serviço apropriada (partilhada ou premium). Uma instância partilhada pode ser afetada com atrasos e limitações da ligação mais longos do que o habitual, uma vez que estão a ser utilizados por outros inquilinos do servidor partilhado. Se necessitar de um desempenho mais previsível e operações de latência baixa fiáveis, considere escolher a opção premium.
  • Confirme que realiza as repetições ao nível ou âmbito adequado para evitar operações não idempotentes que podem causar a inconsistência dos dados. Idealmente, todas as operações devem ser idempotentes para que possam ser repetidas sem causar qualquer inconsistência. Quando este não for o caso, a nova tentativa deve ser realizada em um nível ou escopo que permita que todas as alterações relacionadas sejam desfeitas se uma operação falhar; por exemplo, de dentro de um escopo transacional. Para obter mais informações, veja Cloud Service Fundamentals Data Access Layer – Transient Fault Handling (Camada de Acesso de Dados Fundamentais do Serviço Cloud – Processamento de Falhas Transitórias).
  • Uma estratégia de intervalo fixo não é recomendada para uso com o Banco de Dados SQL do Azure, exceto para cenários interativos em que há apenas algumas tentativas em intervalos curtos. Em vez disso, considere o uso de uma estratégia de back-off exponencial para a maioria dos cenários.
  • Escolha um valor adequado para os tempos limite da ligação e do comando quando definir as ligações. Um tempo limite demasiado curto pode levar falhas prematuras nas ligações quando a base de dados está ocupada. Um tempo limite demasiado longo pode impedir que a lógica de repetição funcione corretamente ao aguardar demasiado antes de detetar uma falha de ligação. O valor do tempo limite é um componente da latência de ponta a ponta; ele é efetivamente adicionado ao atraso de repetição especificado na política de repetição para cada tentativa de repetição.
  • Feche a conexão após algumas tentativas, mesmo ao usar uma lógica de repetição de recuo exponencial, e tente novamente a operação em uma nova conexão. A repetição da mesma operação várias vezes na mesma ligação pode acarretar problemas de ligação. Para obter um exemplo desta técnica, veja Cloud Service Fundamentals Data Access Layer – Transient Fault Handling (Camada de Acesso de Dados Fundamentais do Serviço Cloud – Processamento de Falhas Transitórias).
  • Quando o pool de conexões está em uso (o padrão), há uma chance de que a mesma conexão seja escolhida do pool, mesmo depois de fechar e reabrir uma conexão. Em caso afirmativo, uma técnica para resolvê-lo é chamar o método ClearPool da classe SqlConnection para marcar a conexão como não reutilizável. No entanto, deve realizar este procedimento apenas após várias tentativas de ligação sem sucesso e apenas quando encontrar a classe específica das falhas transitórias, tal como tempos limite de SQL (código de erro -2) relacionados a ligações com falha.
  • Se o código de acesso de dados utilizar transações iniciadas como instâncias TransactionScope, a lógica de repetição deverá reabrir a ligação e iniciar um novo âmbito de transação. Por este motivo, o bloco de código de repetição deve abranger o âmbito completo da transação.

Considere iniciar com as seguintes definições para repetir operações. Essas configurações são de uso geral, e você deve monitorar as operações e ajustar os valores para se adequar ao seu próprio cenário.

Contexto Alvo da amostra E2E
latência máxima
Estratégia de repetição Definições Valores Como funciona
Interativo, IU
ou primeiro plano
2 s FixedInterval Contagem de repetições
Intervalo de repetições
Primeira repetição rápida
3
500 ms
verdadeiro
Tentativa 1 – atraso de 0 s
Tentativa 2 – atraso de 500 ms
Tentativa 3 – atraso de 500 ms
Fundo
ou lote
30 segundos ExponentialBackoff Contagem de repetições
Término mín.
Término máx.
Término delta
Primeira repetição rápida
5
0 s
60 s
2 s
false
Tentativa 1 – atraso de 0 s
Tentativa 2 – atraso de ~2 s
Tentativa 3 – atraso de ~6 s
Tentativa 4 – atraso de ~14 s
Tentativa 5 – atraso de ~30 s

Nota

Os destinos de latência de ponto a ponto assumem o tempo limite predefinido para as ligações ao serviço. Se especificar tempos limite de ligação mais longos, a latência de ponto a ponto será expandida com esse tempo adicional em cada tentativa de repetição.

Exemplos

Esta secção mostra como pode utilizar o Polly para aceder à Base de Dados SQL do Azure com um conjunto de políticas de repetição configurado na classe Policy.

O código seguinte mostra um método de extensão na classe SqlCommand que chama ExecuteAsync com o término exponencial.

public async static Task<SqlDataReader> ExecuteReaderWithRetryAsync(this SqlCommand command)
{
    GuardConnectionIsNotNull(command);

    var policy = Policy.Handle<Exception>().WaitAndRetryAsync(
        retryCount: 3, // Retry 3 times
        sleepDurationProvider: attempt => TimeSpan.FromMilliseconds(200 * Math.Pow(2, attempt - 1)), // Exponential backoff based on an initial 200 ms delay.
        onRetry: (exception, attempt) =>
        {
            // Capture some information for logging/telemetry.
            logger.LogWarn($"ExecuteReaderWithRetryAsync: Retry {attempt} due to {exception}.");
        });

    // Retry the following call according to the policy.
    await policy.ExecuteAsync<SqlDataReader>(async token =>
    {
        // This code is executed within the Policy

        if (conn.State != System.Data.ConnectionState.Open) await conn.OpenAsync(token);
        return await command.ExecuteReaderAsync(System.Data.CommandBehavior.Default, token);

    }, cancellationToken);
}

Este método de extensão assíncrono pode ser utilizado da seguinte forma.

var sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "[some query]";

using (var reader = await sqlCommand.ExecuteReaderWithRetryAsync())
{
    // Do something with the values
}

Próximos passos

Banco de dados SQL usando o Entity Framework 6

A Base de Dados SQL é uma base de dados SQL alojada disponível num intervalo de tamanhos e como um serviço standard (partilhado) e premium (não partilhado). O Entity Framework é um mapeador de objetos relacionais que permite aos programadores .NET trabalhar com dados relacionais com objetos específicos de domínio. Elimina a necessidade da maior parte do código de acesso a dados que os programadores normalmente têm de escrever.

Mecanismo de repetição

O suporte a novas tentativas é fornecido ao acessar o Banco de dados SQL usando o Entity Framework 6.0 e superior por meio de um mecanismo chamado Resiliência de conexão/lógica de repetição. As principais funcionalidades do mecanismo de repetição são:

  • A abstração principal é a interface IDbExecutionStrategy. Esta interface:
    • Define métodos Execute síncronos e assíncronos.
    • Define as classes que podem ser utilizadas diretamente ou podem ser configuradas num contexto de base de dados como uma estratégia predefinida, mapeadas para o nome do fornecedor ou mapeadas para um nome de fornecedor e o nome do servidor. Quando configurada num contexto, as repetições ocorrem ao nível das operações da base de dados individual, das quais podem existir várias para uma determinada operação de contexto.
    • Define quando deve repetir uma ligação falhada e como.
  • Ele inclui várias implementações internas da interface IDbExecutionStrategy :
    • Padrão: sem novas tentativas.
    • Padrão para o Banco de dados SQL (automático): sem novas tentativas, mas inspeciona exceções e as encapsula com sugestões para usar a estratégia do Banco de dados SQL.
    • Padrão para Banco de dados SQL: exponencial (herdado da classe base) mais lógica de deteção do Banco de dados SQL.
  • Implementa uma estratégia de término exponencial que inclui aleatoriedade.
  • As classes de repetição internas são stateful e não são thread-safe. No entanto, podem ser reutilizadas depois de concluída a operação atual.
  • Se a contagem de repetições especificada for excedida, os resultados serão encapsulados num wrapper numa nova exceção. Não borbulha a exceção atual.

Configuração da política

O suporte de repetição é fornecido ao aceder à Base de Dados SQL com o Entity Framework 6.0 e superior. As políticas de repetição são configuradas através de programação. A configuração não pode ser alterada por operação.

Quando configurar uma estratégia no contexto como predefinição, deve especificar uma função para criar uma nova estratégia a pedido. O código seguinte mostra como pode criar uma classe de configuração da repetição que expande a classe base DbConfiguration.

public class BloggingContextConfiguration : DbConfiguration
{
  public BlogConfiguration()
  {
    // Set up the execution strategy for SQL Database (exponential) with 5 retries and 4 sec delay
    this.SetExecutionStrategy(
         "System.Data.SqlClient", () => new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(4)));
  }
}

Em seguida, pode especificar esta como a estratégia de repetição predefinida para todas as operações, com o método SetConfiguration da instância DbConfiguration quando a aplicação inicia. Por predefinição, o EF deteta e utiliza automaticamente a classe de configuração.

DbConfiguration.SetConfiguration(new BloggingContextConfiguration());

Pode especificar a classe de configuração de repetição para um contexto ao anotar a classe de contexto com um atributo DbConfigurationType. No entanto, se tiver apenas uma classe de configuração, o EF vai utilizá-la sem que seja preciso anotar o contexto.

[DbConfigurationType(typeof(BloggingContextConfiguration))]
public class BloggingContext : DbContext

Se precisar de utilizar estratégias de repetição diferentes para operações específicas, ou desativar as repetições para operações específicas, poderá criar uma classe de configuração que lhe permite suspender ou trocar as estratégias ao definir um sinalizador em CallContext. A classe de configuração pode utilizar este sinalizador para alternar estratégias ou desativar a estratégia que forneceu e utilizar uma estratégia predefinida. Para obter mais informações, consulte Suspender estratégia de execução (EF6 em diante).

Outra técnica para utilizar estratégias de repetição específicas para operações individuais consiste em criar uma instância da classe de estratégia necessária e fornecer as definições pretendidas através de parâmetros. Em seguida, invoque o método ExecuteAsync.

var executionStrategy = new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(4));
var blogs = await executionStrategy.ExecuteAsync(
    async () =>
    {
        using (var db = new BloggingContext("Blogs"))
        {
            // Acquire some values asynchronously and return them
        }
    },
    new CancellationToken()
);

A forma mais simples de utilizar uma classe DbConfiguration é localizá-la na mesma assemblagem que a classe DbContext. No entanto, isso não é apropriado quando o mesmo contexto é necessário em diferentes cenários, como diferentes estratégias interativas e de repetição em segundo plano. Se os diferentes contextos forem executados em AppDomains separados, poderá utilizar o suporte incorporado para especificar classes de configuração no ficheiro de configuração ou defini-lo explicitamente com o código. Se os diferentes contextos tiverem de ser executados no mesmo AppDomain, será fornecida uma solução personalizada.

Para obter mais informações, veja Code-Based Configuration (EF6 onwards) (Configuração Baseada no Código (EF6 em diante)).

A tabela seguinte mostra as predefinições da política de repetição incorporada quando utiliza o EF6.

Definição Default value Significado
Política Exponencial Término exponencial.
MaxRetryCount 5 O número máximo de repetições.
MaxDelay 30 segundos O atraso máximo entre repetições. Esse valor não afeta como a série de atrasos é calculada. Apenas define um limite superior.
DefaultCoefficient 1 segundo O coeficiente para o cálculo do término exponencial. Não é possível alterar este valor.
DefaultRandomFactor 1.1 O multiplicador utilizado para adicionar um atraso aleatório para cada entrada. Não é possível alterar este valor.
DefaultExponentialBase 2 O multiplicador utilizado para calcular o próximo atraso. Não é possível alterar este valor.

Orientações sobre a utilização da repetição

Considere as seguintes diretrizes ao aceder à Base de Dados SQL com o EF6:

  • Escolha a opção de serviço apropriada (partilhada ou premium). Uma instância partilhada pode ser afetada com atrasos e limitações da ligação mais longos do que o habitual, uma vez que estão a ser utilizados por outros inquilinos do servidor partilhado. Se necessitar de um desempenho previsível e operações de latência baixa fiáveis, considere optar pela opção premium.

  • Uma estratégia de intervalo fixo não é recomendada para uso com o Banco de Dados SQL do Azure. Em alternativa, utilize uma estratégia de término exponencial, pois o serviço pode ficar sobrecarregado e os atrasos mais longos permitem mais tempo de recuperação.

  • Escolha um valor adequado para os tempos limite da ligação e do comando quando definir as ligações. Baseie o tempo limite na criação da lógica de negócio e em testes. Pode ter de modificar este valor ao longo do tempo à medida que os volumes de dados ou os processos de negócio se alteram. Um tempo limite demasiado curto pode levar falhas prematuras nas ligações quando a base de dados está ocupada. Um tempo limite demasiado longo pode impedir que a lógica de repetição funcione corretamente ao aguardar demasiado antes de detetar uma falha de ligação. O valor do tempo limite é um componente da latência de ponta a ponta, embora você não possa determinar facilmente quantos comandos serão executados ao salvar o contexto. Pode alterar o tempo limite predefinido ao definir a propriedade CommandTimeout da instância DbContext.

  • O Entity Framework suporta configurações de repetição definidas nos ficheiros de configuração. No entanto, para obter uma flexibilidade máxima no Azure, deve considerar criar a configuração através de programação na aplicação. Os parâmetros específicos das políticas de repetição, como o número de repetições e os intervalos de repetição, podem ser armazenados no ficheiro de configuração do serviço e utilizados no tempo de execução para criar as políticas adequadas. Tal permite que as definições sejam alteradas sem a necessidade de reiniciar a aplicação.

Considere iniciar com as seguintes definições para repetir operações. Não é possível especificar o atraso entre as tentativas de repetição (ele é corrigido e gerado como uma sequência exponencial). Pode especificar apenas os valores máximos, conforme mostrado aqui; a menos que crie uma estratégia de repetição personalizada. Essas configurações são de uso geral, e você deve monitorar as operações e ajustar os valores para se adequar ao seu próprio cenário.

Contexto Alvo da amostra E2E
latência máxima
Política de repetição Definições Valores Como funciona
Interativo, IU
ou primeiro plano
2 segundos Exponencial MaxRetryCount
MaxDelay
3
750 ms
Tentativa 1 – atraso de 0 s
Tentativa 2 – atraso de 750 ms
Tentativa 3 – atraso 750 ms
Fundo
ou lote
30 segundos Exponencial MaxRetryCount
MaxDelay
5
12 segundos
Tentativa 1 – atraso de 0 s
Tentativa 2 – atraso de ~1 s
Tentativa 3 – atraso de ~3 s
Tentativa 4 – atraso de ~7 s
Tentativa 5 – atraso de ~12 s

Nota

Os destinos de latência de ponto a ponto assumem o tempo limite predefinido para as ligações ao serviço. Se especificar tempos limite de ligação mais longos, a latência de ponto a ponto será expandida com esse tempo adicional em cada tentativa de repetição.

Exemplos

O exemplo de código seguinte define uma solução de acesso de dados simples que utiliza o Entity Framework. Define uma estratégia de repetição específica através da definição de uma instância de uma classe denominada BlogConfiguration que expande a DbConfiguration.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.SqlServer;
using System.Threading.Tasks;

namespace RetryCodeSamples
{
    public class BlogConfiguration : DbConfiguration
    {
        public BlogConfiguration()
        {
            // Set up the execution strategy for SQL Database (exponential) with 5 retries and 12 sec delay.
            // These values could be loaded from configuration rather than being hard-coded.
            this.SetExecutionStrategy(
                    "System.Data.SqlClient", () => new SqlAzureExecutionStrategy(5, TimeSpan.FromSeconds(12)));
        }
    }

    // Specify the configuration type if more than one has been defined.
    // [DbConfigurationType(typeof(BlogConfiguration))]
    public class BloggingContext : DbContext
    {
        // Definition of content goes here.
    }

    class EF6CodeSamples
    {
        public async static Task Samples()
        {
            // Execution strategy configured by DbConfiguration subclass, discovered automatically or
            // or explicitly indicated through configuration or with an attribute. Default is no retries.
            using (var db = new BloggingContext("Blogs"))
            {
                // Add, edit, delete blog items here, then:
                await db.SaveChangesAsync();
            }
        }
    }
}

Mais exemplos de uso do mecanismo de repetição do Entity Framework podem ser encontrados em Resiliência de conexão/lógica de repetição.

Banco de dados SQL usando o Entity Framework Core

O Entity Framework Core é um mapeador de objetos relacionais que permite aos programadores .NET Core trabalhar com dados com objetos específicos de domínio. Elimina a necessidade da maior parte do código de acesso a dados que os programadores normalmente têm de escrever. Esta versão do Entity Framework foi escrita a partir do zero e não herda automaticamente todas as funcionalidades do EF6.x.

Mecanismo de repetição

O suporte a novas tentativas é fornecido ao acessar o Banco de dados SQL usando o Entity Framework Core por meio de um mecanismo chamado resiliência de conexão. A resiliência de ligação foi introduzida no EF Core 1.1.0.

A abstração primária é a interface IExecutionStrategy. A estratégia de execução do SQL Server, incluindo o SQL Azure, é compatível com os tipos de exceção que podem ser repetidos e possui predefinições sensíveis para o máximo de repetições, atraso entre repetições, entre outros.

Exemplos

O seguinte código permite repetições automáticas ao configurar o objeto DbContext, que representa uma sessão com a base de dados.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=EFMiscellaneous.ConnectionResiliency;Trusted_Connection=True;",
            options => options.EnableRetryOnFailure());
}

O código seguinte mostra como executar uma transação com repetições automáticas, ao utilizar uma estratégia de execução. A transação é definida num delegado. Se ocorrer uma falha transitória, a estratégia de execução invocará o delegado novamente.

using (var db = new BloggingContext())
{
    var strategy = db.Database.CreateExecutionStrategy();

    strategy.Execute(() =>
    {
        using (var transaction = db.Database.BeginTransaction())
        {
            db.Blogs.Add(new Blog { Url = "https://blogs.msdn.com/dotnet" });
            db.SaveChanges();

            db.Blogs.Add(new Blog { Url = "https://blogs.msdn.com/visualstudio" });
            db.SaveChanges();

            transaction.Commit();
        }
    });
}

Armazenamento do Azure

Os serviços de Armazenamento do Azure incluem armazenamento de blobs, arquivos e filas de armazenamento.

Blobs, filas e arquivos

A classe ClientOptions é o tipo base para todos os tipos de opção de cliente e expõe várias opções de cliente comuns, como Diagnostics, Retry, Transport. Para fornecer as opções de configuração do cliente para se conectar à Fila, Blob e Armazenamento de Arquivos do Azure, você deve usar o tipo derivado correspondente. No próximo exemplo, você usa a classe QueueClientOptions (derivada de ClientOptions) para configurar um cliente para se conectar ao Serviço de Fila do Azure. A propriedade Retry é o conjunto de opções que podem ser especificadas para influenciar como as tentativas de repetição são feitas e como uma falha é qualificada para ser repetida.

using System;
using System.Threading;
using Azure.Core;
using Azure.Identity;
using Azure.Storage;
using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;

namespace RetryCodeSamples
{
    class AzureStorageCodeSamples {

        public async static Task Samples() {

               // Provide the client configuration options for connecting to Azure Queue Storage
                QueueClientOptions queueClientOptions = new QueueClientOptions()
                {
                    Retry = {
                    Delay = TimeSpan.FromSeconds(2),     //The delay between retry attempts for a fixed approach or the delay on which to base
                                                         //calculations for a backoff-based approach
                    MaxRetries = 5,                      //The maximum number of retry attempts before giving up
                    Mode = RetryMode.Exponential,        //The approach to use for calculating retry delays
                    MaxDelay = TimeSpan.FromSeconds(10)  //The maximum permissible delay between retry attempts
                    },

                    GeoRedundantSecondaryUri = new Uri("https://...")
                    // If the GeoRedundantSecondaryUri property is set, the secondary Uri will be used for GET or HEAD requests during retries.
                    // If the status of the response from the secondary Uri is a 404, then subsequent retries for the request will not use the
                    // secondary Uri again, as this indicates that the resource may not have propagated there yet.
                    // Otherwise, subsequent retries will alternate back and forth between primary and secondary Uri.
                };

                Uri queueServiceUri = new Uri("https://storageaccount.queue.core.windows.net/");
                string accountName = "Storage account name";
                string accountKey = "storage account key";

                // Create a client object for the Queue service, including QueueClientOptions.
                QueueServiceClient serviceClient = new QueueServiceClient(queueServiceUri, new DefaultAzureCredential(), queueClientOptions);

                CancellationTokenSource source = new CancellationTokenSource();
                CancellationToken cancellationToken = source.Token;

                // Return an async collection of queues in the storage account.
                var queues = serviceClient.GetQueuesAsync(QueueTraits.None, null, cancellationToken);

Suporte de mesa

Nota

O Pacote Nuget WindowsAzure.Storage e o Pacote Nuget Microsoft.Azure.Cosmos.Table foram preteridos. Para obter suporte à tabela do Azure, consulte Azure.Data.Tables Nuget Package

Mecanismo de repetição

A biblioteca de cliente é baseada na biblioteca Azure Core, que é uma biblioteca que fornece serviços transversais para outras bibliotecas de cliente.

Há muitas razões pelas quais a falha pode ocorrer quando um aplicativo cliente tenta enviar uma solicitação de rede para um serviço. Alguns exemplos são tempo limite, falhas de infraestrutura de rede, serviço rejeitando a solicitação devido a limitação/ocupado, instância de serviço terminando devido à redução da escala do serviço, instância de serviço descendo para ser substituída por outra versão, falha do serviço devido a uma exceção não tratada, etc. Ao oferecer um mecanismo de repetição integrado (com uma configuração padrão que o consumidor pode substituir), nossos SDKs e o aplicativo do consumidor tornam-se resilientes a esses tipos de falhas. Observe que alguns serviços cobram dinheiro real por cada solicitação e, portanto, os consumidores devem ser capazes de desativar totalmente as tentativas se preferirem economizar dinheiro em vez de resiliência.

Configuração da política

As políticas de repetição são configuradas através de programação. A configuração é baseada na classe RetryOption. Há um atributo em TableClientOptions herdado de ClientOptions

      var tableClientOptions = new TableClientOptions();
      tableClientOptions.Retry.Mode = RetryMode.Exponential;
      tableClientOptions.Retry.MaxRetries = 5;
      var serviceClient = new TableServiceClient(connectionString, tableClientOptions);

As tabelas a seguir mostram as possibilidades para as políticas de repetição internas.

RetryOption

Definição Significado
Atraso O atraso entre as tentativas de repetição de uma abordagem fixa ou o atraso no qual basear os cálculos para uma abordagem baseada em backoff. Se o serviço fornecer um cabeçalho de resposta Retry-After, a próxima repetição será atrasada pela duração especificada pelo valor do cabeçalho.
MaxDelay O atraso máximo permitido entre as tentativas de repetição quando o serviço não fornece um cabeçalho de resposta Retry-After. Se o serviço fornecer um cabeçalho de resposta Retry-After, a próxima repetição será atrasada pela duração especificada pelo valor do cabeçalho.
Modo A abordagem a ser usada para calcular atrasos de repetição.
NetworkTimeout O tempo limite aplicado a operações de rede individuais.

RetryMode

Definição Significado
Exponencial As tentativas de repetição serão atrasadas com base em uma estratégia de backoff, onde cada tentativa aumentará a duração que espera antes de tentar novamente.
MaxDelay As tentativas de repetição acontecem em intervalos fixos; cada atraso tem uma duração consistente.

Telemetria

A maneira mais simples de ver os logs é habilitar o registro em log do console. Para criar um ouvinte de log do SDK do Azure que envia mensagens para o console, use o método AzureEventSourceListener.CreateConsoleLogger.

      // Setup a listener to monitor logged events.
      using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

Exemplos

Executar o exemplo de código a seguir com o emulador de armazenamento desligado nos permitirá ver informações sobre novas tentativas no console.

using Azure.Core;
using Azure.Core.Diagnostics;
using Azure.Data.Tables;
using Azure.Data.Tables.Models;

namespace RetryCodeSamples
{
    class AzureStorageCodeSamples
    {
        private const string connectionString = "UseDevelopmentStorage=true";
        private const string tableName = "RetryTestTable";

        public async static Task SamplesAsync()
        {
            // Setup a listener to monitor logged events.
            using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

            var tableClientOptions = new TableClientOptions();
            tableClientOptions.Retry.Mode = RetryMode.Exponential;
            tableClientOptions.Retry.MaxRetries = 5;

            var serviceClient = new TableServiceClient(connectionString, tableClientOptions);

            TableItem table = await serviceClient.CreateTableIfNotExistsAsync(tableName);
            Console.WriteLine($"The created table's name is {table.Name}.");
        }
    }
}

Diretrizes gerais de repetições e REST

Considere o seguinte ao acessar o Azure ou serviços de terceiros:

  • Utilize uma abordagem sistemática para gerir várias repetições, talvez como código reutilizável, para que possa aplicar uma metodologia consistente em todos os clientes e todas as soluções.

  • Considere o uso de uma estrutura de repetição como Polly para gerenciar novas tentativas se o serviço ou cliente de destino não tiver nenhum mecanismo de repetição interno. Tal ajudará a implementar um comportamento de repetição consistente e pode fornecer uma estratégia de repetição predefinida adequada ao serviço de destino. No entanto, talvez seja necessário criar um código de repetição personalizado para serviços com comportamento não padrão que não dependem de exceções para indicar falhas transitórias ou se você quiser usar uma resposta de repetição e resposta para gerenciar o comportamento de repetição.

  • A lógica de deteção transitória vai depender da API de cliente atual que utiliza para invocar as chamadas REST. Alguns clientes, como a classe HttpClient mais recente, não lançarão exceções para solicitações concluídas com um código de status HTTP sem êxito.

  • O código de estado HTTP devolvido do serviço pode ajudar a indicar se a falha é transitória. Pode ter de examinar as exceções geradas por um cliente ou a estrutura de repetição para aceder ao código de estado ou para determinar o tipo de exceção equivalente. Os seguintes códigos HTTP normalmente indicam que uma repetição é adequada:

    • 408 Tempo Limite do Pedido
    • Demasiados Pedidos 429
    • 500 Erro de Servidor Interno
    • 502 Gateway Incorreto
    • 503 Serviço Indisponível
    • 504 Tempo Limite do Gateway
  • Se basear a sua lógica de repetição em exceções, o seguinte normalmente indicará uma falha transitória quando não for possível estabelecer ligação:

    • WebExceptionStatus.ConnectionClosed
    • WebExceptionStatus.ConnectFailure
    • WebExceptionStatus.Timeout
    • WebExceptionStatus.RequestCanceled
  • No caso de um estado de serviço indisponível, o serviço pode indicar o atraso adequado antes de repetir no cabeçalho de resposta Retry-After ou num cabeçalho personalizado diferente. Os serviços também podem enviar informações adicionais como cabeçalhos personalizados ou incorporados no conteúdo da resposta.

  • Não tente novamente para códigos de status que representam erros do cliente (erros no intervalo 4xx), exceto para um tempo limite de solicitação 408 e 429 solicitações demais.

  • Teste cuidadosamente as estratégias de repetição e os mecanismos numa série de condições, por exemplo, estados de rede diferentes e carregamentos de sistema variáveis.

Estratégias de repetição

Seguem-se os habituais tipos de intervalos de estratégia de repetição:

  • Exponencial. Uma política de repetição que executa um número especificado de tentativas, usando uma abordagem de back-off exponencial randomizada para determinar o intervalo entre as tentativas. Por exemplo:

    var random = new Random();
    
    var delta = (int)((Math.Pow(2.0, currentRetryCount) - 1.0) *
                random.Next((int)(this.deltaBackoff.TotalMilliseconds * 0.8),
                (int)(this.deltaBackoff.TotalMilliseconds * 1.2)));
    var interval = (int)Math.Min(checked(this.minBackoff.TotalMilliseconds + delta),
                    this.maxBackoff.TotalMilliseconds);
    retryInterval = TimeSpan.FromMilliseconds(interval);
    
  • Incremental. Uma estratégia de repetição com um número especificado de tentativas de repetição e um intervalo de tempo incremental entre as tentativas. Por exemplo:

    retryInterval = TimeSpan.FromMilliseconds(this.initialInterval.TotalMilliseconds +
                    (this.increment.TotalMilliseconds * currentRetryCount));
    
  • LinearRetry. Uma política de repetição que executa um número especificado de tentativas, usando um intervalo de tempo fixo especificado entre as tentativas. Por exemplo:

    retryInterval = this.deltaBackoff;
    

Processamento de falhas transitórias com o Polly

Polly é uma biblioteca para lidar programaticamente com repetições e estratégias de disjuntores . O projeto Polly é um membro da .NET Foundation. Para serviços em que o cliente não suporta nativamente tentativas, o Polly é uma alternativa válida e evita a necessidade de escrever código de repetição personalizado, o que pode ser difícil de implementar corretamente. O Polly também fornece uma forma de controlar os erros quando estes ocorrem, para que possa registar as repetições.

Próximos passos