As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Tente novamente com o padrão de recuo
Intenção
O padrão de nova tentativa com recuo melhora a estabilidade do aplicativo ao repetir de forma transparente as operações que falham devido a erros transitórios.
Motivação
Em arquiteturas distribuídas, erros transitórios podem ser causados por limitação de serviços, perda temporária de conectividade de rede ou indisponibilidade temporária do serviço. A repetição automática de operações que falham devido a esses erros transitórios melhora a experiência do usuário e a resiliência do aplicativo. No entanto, repetições frequentes podem sobrecarregar a largura de banda da rede e causar contenção. O recuo exponencial é uma técnica em que as operações são repetidas aumentando os tempos de espera para um número específico de tentativas.
Aplicabilidade
Use o padrão de nova tentativa com recuo quando:
-
Seus serviços frequentemente limitam a solicitação para evitar sobrecarga, resultando em um429 Demasiados pedidosexceção ao processo de chamada.
-
A rede é um participante invisível em arquiteturas distribuídas, e problemas temporários de rede resultam em falhas.
-
O serviço que está sendo chamado está temporariamente indisponível, causando falhas. Tentativas frequentes podem causar degradação do serviço, a menos que você introduza um tempo limite de recuo usando esse padrão.
Questões e considerações
-
Idempotência: se várias chamadas para o método tiverem o mesmo efeito de uma única chamada no estado do sistema, a operação será considerada idempotente. As operações devem ser idempotentes quando você usa o padrão de nova tentativa com recuo. Caso contrário, atualizações parciais podem corromper o estado do sistema.
-
Largura de banda da rede: A degradação do serviço pode ocorrer se muitas tentativas ocuparem a largura de banda da rede, resultando em tempos de resposta lentos.
-
Cenários de falha rápida: Para erros não transitórios, se você puder determinar a causa da falha, é mais eficiente falhar rapidamente usando o padrão do disjuntor.
-
Taxa de recuo: A introdução do retrocesso exponencial pode ter um impacto no tempo limite do serviço, resultando em tempos de espera mais longos para o usuário final.
Implementação
Arquitetura de alto nível
O diagrama a seguir ilustra como o Serviço A pode repetir as chamadas para o Serviço B até que uma resposta bem-sucedida seja retornada. Se o Serviço B não retornar uma resposta bem-sucedida após algumas tentativas, o Serviço A poderá parar de tentar novamente e retornar uma falha ao chamador.
![Arquitetura de alto nível para nova tentativa com padrão de recuo](images/retry-backoff-1.png)
Implementação usandoAWSserviços
O diagrama a seguir mostra um fluxo de trabalho de processamento de tickets em uma plataforma de suporte ao cliente. Os tíquetes de clientes insatisfeitos são acelerados com o aumento automático da prioridade do ticket. OTicket info
A função Lambda extrai os detalhes do ticket e chama oGet sentiment
Função lambda. OGet sentiment
A função Lambda verifica os sentimentos do cliente passando a descrição paraAmazon Compreende
Se a chamada para oGet sentiment
A função Lambda falha, o fluxo de trabalho repete a operação três vezes.AWS Step Functionspermite o recuo exponencial ao permitir que você configure o valor do recuo.
Neste exemplo, no máximo três tentativas são configuradas com um multiplicador de aumento de 1,5 segundos. Se a primeira tentativa ocorrer após 3 segundos, a segunda tentativa ocorrerá após 3 x 1,5 segundos = 4,5 segundos e a terceira tentativa ocorrerá após 4,5 x 1,5 segundos = 6,75 segundos. Se a terceira tentativa não for bem-sucedida, o fluxo de trabalho falhará. A lógica de retrocesso não requer nenhum código personalizado, ela é fornecida como uma configuração peloAWS Step Functions.
![Tente novamente com o padrão de recuo comAWSserviços](images/retry-backoff-2.png)
Código de exemplo
O código a seguir mostra a implementação do padrão de nova tentativa com recuo.
public async Task DoRetriesWithBackOff() { int retries = 0; bool retry; do { //Sample object for sending parameters var parameterObj = new InputParameter { SimulateTimeout = "false" }; var content = new StringContent(JsonConvert.SerializeObject(parameterObj), System.Text.Encoding.UTF8, "application/json"); var waitInMilliseconds = Convert.ToInt32((Math.Pow(2, retries) - 1) * 100); System.Threading.Thread.Sleep(waitInMilliseconds); var response = await _client.PostAsync(_baseURL, content); switch (response.StatusCode) { //Success case HttpStatusCode.OK: retry = false; Console.WriteLine(response.Content.ReadAsStringAsync().Result); break; //Throttling, timeouts case HttpStatusCode.TooManyRequests: case HttpStatusCode.GatewayTimeout: retry = true; break; //Some other error occured, so stop calling the API default: retry = false; break; } retries++; } while (retry && retries < MAX_RETRIES); }
GitHubrepositório
Para uma implementação completa da arquitetura de exemplo para esse padrão, consulte aGitHubrepositório emhttps://github.com/aws-samples/retry-with-backoff
Conteúdo relacionado
-
Tempos limite, novas tentativas e recuos com instabilidade
(Biblioteca do Amazon Builders)