View a markdown version of this page

Tentativas e tempos limite - AWS SDK para Go v2

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á.

Tentativas e tempos limite

O AWS SDK para Go permite que você configure o comportamento de repetição de solicitações para serviços HTTP. Por padrão, os clientes de serviço usam retry.Standard como mecanismo padrão de novas tentativas. Se a configuração ou o comportamento padrão não atenderem aos requisitos da aplicação, você poderá ajustar a configuração do mecanismo de novas tentativas ou fornecer sua própria implementação desse mecanismo.

O AWS SDK para Go fornece uma interface AWS.Retryer que define o conjunto de métodos exigidos pela implementação de uma nova tentativa. O SDK fornece duas implementações para novas tentativas: retry.standard e aws. NoOpRetryer.

Mecanismo padrão de novas tentativas

O mecanismo de novas tentativas retry.Standard é a implementação aws.Retryer padrão usada por clientes do SDK. O mecanismo padrão de novas tentativas tem taxas limitadas, com um número máximo configurável de tentativas e a capacidade de ajustar a política de espera entre as solicitações.

A tabela a seguir define os valores padrão para esse mecanismo de novas tentativas:

Propriedade Padrão

Número máximo de tentativas

3

Atraso máximo entre tentativas

20 segundos

Quando ocorre um erro de novas tentativas ao invocar a solicitação, o mecanismo padrão de novas tentativas usa a configuração fornecida para adiar e, posteriormente, tentar novamente a solicitação. As novas tentativas aumentam a latência geral da solicitação, e você deverá configurar o mecanismo de novas tentativas se a configuração padrão não atender aos requisitos da aplicação.

Consulte detalhes sobre quais erros são considerados passíveis de nova tentativa pela implementação do mecanismo padrão de novas tentativas na documentação do pacote de novas tentativas.

NopRetryer

As leis. NopRetryeré uma aws.Retryer implementação fornecida se você quiser desativar todas as tentativas de repetição. Ao invocar uma operação de cliente de serviço, essa nova tentativa só permitirá que a solicitação seja tentada uma vez, e qualquer erro resultante será retornado à aplicação de chamada.

Personalizar comportamento

O SDK fornece um conjunto de utilitários auxiliares que encapsulam uma implementação aws.Retryer e retorna o mecanismo de novas tentativas fornecido encapsulado com o comportamento desejado de novas tentativas. É possível substituir o mecanismo padrão de novas tentativas para todos os clientes, por cliente ou por operação, dependendo dos requisitos das aplicações. Consulte mais exemplos que mostram como fazer isso na documentação do pacote de novas tentativas.

Atenção

Ao especificar uma implementação aws.Retryer global usando config.WithRetryer, você deve garantir o retorno de uma nova instância de aws.Retryer a cada invocação. Isso garante que você não crie um bucket global de tokens de novas tentativas em todos os clientes de serviço.

Limitar o número máximo de tentativas

Você usa a repetição. AddWithMaxAttemptspara empacotar uma aws.Retryer implementação para definir o número máximo de tentativas para o valor desejado.

Atenção

Usar retry.AddWithMaxAttempts com um valor zero permitirá que o SDK tente novamente todos os erros passíveis de novas tentativas até que a solicitação seja bem-sucedida ou que um erro que não possa ter uma nova tentativa seja retornado. Permitir que o SDK tente novamente indefinidamente pode resultar em workloads descontroladas e ciclos de faturamento inflados.

import "context" import "github.com/aws/aws-sdk-go-v2/aws/retry" import "github.com/aws/aws-sdk-go-v2/config" import "github.com/aws/aws-sdk-go-v2/service/s3" // ... // MaxAttempts will be infinite (will retry indefinitely) cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer { return retry.AddWithMaxAttempts(retry.NewStandard(), 0) })) if err != nil { return err } client := s3.NewFromConfig(cfg)

Observe que instanciar uma nova tentativa usando opções funcionais para definir MaxAttempts diretamente terá um comportamento um pouco diferente. Mais especificamente, definir um valor menor ou igual a zero fará com que o mecanismo de novas tentativas use o máximo padrão de três tentativas, em vez de tentar novamente indefinidamente:

import "context" import "github.com/aws/aws-sdk-go-v2/aws/retry" import "github.com/aws/aws-sdk-go-v2/config" import "github.com/aws/aws-sdk-go-v2/service/s3" // ... // MaxAttempts will default to 3 cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer { return retry.NewStandard(func(o *retry.StandardOptions) { o.MaxAttempts = 0 }) })) if err != nil { return err } client := s3.NewFromConfig(cfg)

Limitar o atraso máximo de backoff

Você usa a repetição. AddWithMaxBackoffDelaypara encerrar uma aws.Retryer implementação e limitar o atraso máximo que pode ocorrer entre a repetição de uma solicitação com falha.

Por exemplo, você pode usar o código a seguir para encapsular o mecanismo padrão de novas tentativas do cliente com um atraso máximo desejado de cinco segundos:

import "context" import "time" import "github.com/aws/aws-sdk-go-v2/aws/retry" import "github.com/aws/aws-sdk-go-v2/config" import "github.com/aws/aws-sdk-go-v2/service/s3" // ... cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer { return retry.AddWithMaxBackoffDelay(retry.NewStandard(), time.Second*5) })) if err != nil { return err } client := s3.NewFromConfig(cfg)

Tentar novamente códigos de erro adicionais da API

Você usa a repetição. AddWithErrorCodespara empacotar uma aws.Retryer implementação e incluir códigos de erro de API adicionais que devem ser considerados passíveis de nova tentativa.

Por exemplo, você pode usar o código a seguir para encapsular o mecanismo padrão de novas tentativas do cliente para incluir a exceção NoSuchBucketException do Amazon S3 como passível de novas tentativas.

import "context" import "time" import "github.com/aws/aws-sdk-go-v2/aws/retry" import "github.com/aws/aws-sdk-go-v2/config" import "github.com/aws/aws-sdk-go-v2/service/s3" import "github.com/aws/aws-sdk-go-v2/service/s3/types" // ... cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRetryer(func() aws.Retryer { return retry.AddWithErrorCodes(retry.NewStandard(), (*types.NoSuchBucketException)(nil).ErrorCode()) })) if err != nil { return err } client := s3.NewFromConfig(cfg)

Limitação de taxa do lado do cliente

O AWS SDK para Go introduz um novo mecanismo de limitação de taxa do lado do cliente na política de repetição padrão para se alinhar ao comportamento moderno. SDKs Esse comportamento é controlado pelo RateLimitercampo nas opções de um repetidor.

RateLimiter A opera como um token bucket com uma capacidade definida, em que falhas na tentativa de operação consomem tokens. Uma nova tentativa que tenta consumir mais tokens do que os disponíveis resulta em falha na operação com um QuotaExceededError.

A implementação padrão é parametrizada da seguinte forma (como modificar cada configuração):

  • uma capacidade de 500 (defina o valor de RateLimiter ao StandardOptions usar NewTokenRateLimit)

  • uma nova tentativa causada por um tempo limite custa 10 tokens (ativado RetryTimeoutCost ) StandardOptions

  • uma nova tentativa causada por outros erros custa 5 tokens ( RetryCostativada StandardOptions)

  • uma operação bem-sucedida na 1ª tentativa adiciona 1 token ( NoRetryIncrement ativado StandardOptions)

    • operações bem-sucedidas na segunda tentativa ou posterior não adicionam de volta nenhum token

Se você perceber que o comportamento padrão não atende às necessidades da aplicação, você pode desativá-lo com ratelimit.None.

Exemplo: limitador de taxa modificado

import ( "context" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/aws/ratelimit" "github.com/aws/aws-sdk-go-v2/aws/retry" "github.com/aws/aws-sdk-go-v2/config" ) // ... cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryer(func() aws.Retryer { return retry.NewStandard(func(o *retry.StandardOptions) { // Makes the rate limiter more permissive in general. These values are // arbitrary for demonstration and may not suit your specific // application's needs. o.RateLimiter = ratelimit.NewTokenRateLimit(1000) o.RetryCost = 1 o.RetryTimeoutCost = 3 o.NoRetryIncrement = 10 }) }))

Exemplo: sem limite de taxa usando ratelimit.None

import ( "context" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/aws/ratelimit" "github.com/aws/aws-sdk-go-v2/aws/retry" "github.com/aws/aws-sdk-go-v2/config" ) // ... cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryer(func() aws.Retryer { return retry.NewStandard(func(o *retry.StandardOptions) { o.RateLimiter = ratelimit.None }) }))

Tempos limite

Você usa o pacote de contexto para definir tempos limite ou prazos ao invocar uma operação de cliente de serviço. Use o contexto. WithDeadlinepara encapsular o contexto de seus aplicativos e definir um prazo para um horário específico em que a operação invocada deve ser concluída. Para definir um tempo limite após um determinado contexto de time.Duration uso. WithTimeout. O SDK passa o context.Context fornecido para o cliente de transporte HTTP ao invocar uma API de serviço. Se o contexto passado para o SDK for cancelado ou se tornar cancelado ao invocar a operação, o SDK não tentará novamente a solicitação e retornará à aplicação que fez a chamada. Você deve lidar com o cancelamento de contexto de forma adequada na aplicação nos casos em que o contexto fornecido ao SDK tenha sido cancelado.

Definir um tempo limite

O código de exemplo a seguir mostra como definir um tempo limite para uma operação de cliente de serviço.

import "context" import "time" // ... ctx := context.TODO() // or appropriate context.Context value for your application client := s3.NewFromConfig(cfg) // create a new context from the previous ctx with a timeout, e.g. 5 seconds ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() resp, err := client.GetObject(ctx, &s3.GetObjectInput{ // input parameters }) if err != nil { // handle error }