Como soluciono problemas de repetição e tempo limite ao invocar uma função do Lambda usando um AWS SDK?

7 minuto de leitura
0

Quando invoco minha função do AWS Lambda usando um AWS SDK, a função atinge o tempo limite, a solicitação da API para de responder ou uma ação da API é duplicada. Como soluciono esses problemas?

Breve descrição

Há três motivos pelos quais problemas de repetição e tempo limite ocorrem ao invocar uma função do Lambda com um AWS SDK:

  • Uma API remota está inacessível ou leva muito tempo para responder a uma chamada da API.
  • A chamada da API não recebe uma resposta dentro do tempo limite do soquete.
  • A chamada da API não recebe uma resposta dentro do período de tempo limite da função do Lambda.

Observação: as chamadas da API podem levar mais tempo do que o esperado quando ocorrem problemas de conexão de rede. Problemas de rede também podem causar novas tentativas e solicitações de API duplicadas. Para se preparar para essas ocorrências, certifique-se de que sua função do Lambda seja idempotente.

Se você fizer uma chamada da API usando um AWS SDK e a chamada falhar, o AWS SDK repetirá a chamada automaticamente. Quantas vezes o AWS SDK tenta novamente e por quanto tempo é determinado pelas configurações que variam entre cada AWS SDK.

Configurações padrão de nova tentativa do AWS SDK

Observação: alguns valores podem ser diferentes para outros serviços da AWS.

AWS SDKContagem máxima de novas tentativasTempo limite de conexãoTempo limite do soquete
Python (Boto 3)depende do serviço60 segundos60 segundos
JavaScript/Node.jsdepende do serviçoN/A120 segundos
Java310 segundos50 segundos
.NET4100 segundos300 segundos
Go3N/AN/A

Para solucionar os problemas de repetição e tempo limite, primeiro revise os logs da chamada da API para encontrar o problema. Em seguida, altere a contagem de novas tentativas e as configurações de tempo limite do AWS SDK conforme necessário para cada caso de uso. Para permitir tempo suficiente para responder à chamada da API, adicione tempo à configuração de tempo limite da função do Lambda.

Resolução

Registrar as chamadas da API feitas pelo AWS SDK

Use o Amazon CloudWatch Logs para obter detalhes sobre falhas nas conexões e o número de tentativas de novas tentativas para cada uma. Para mais informações, consulte Accessing Amazon CloudWatch logs for AWS Lambda (Como acessar os logs do Amazon CloudWatch para o AWS Lambda). Ou veja as instruções a seguir para o AWS SDK que você está usando:

Exemplo de log de erros em que a chamada da API não conseguiu estabelecer uma conexão (tempo limite de conexão)

START RequestId: b81e56a9-90e0-11e8-bfa8-b9f44c99e76d Version: $LATEST
2018-07-26T14:32:27.393Z    b81e56a9-90e0-11e8-bfa8-b9f44c99e76d    [AWS ec2 undefined 40.29s 3 retries] describeInstances({})
2018-07-26T14:32:27.393Z    b81e56a9-90e0-11e8-bfa8-b9f44c99e76d    { TimeoutError: Socket timed out without establishing a connection

...

Exemplo de log de erros em que a conexão da chamada da API foi bem-sucedida, mas atingiu o tempo limite depois da demora da resposta da API (tempo limite do soquete)

START RequestId: 3c0523f4-9650-11e8-bd98-0df3c5cf9bd8 Version: $LATEST
2018-08-02T12:33:18.958Z    3c0523f4-9650-11e8-bd98-0df3c5cf9bd8    [AWS ec2 undefined 30.596s 3 retries] describeInstances({})
2018-08-02T12:33:18.978Z    3c0523f4-9650-11e8-bd98-0df3c5cf9bd8    { TimeoutError: Connection timed out after 30s

Observação: esses logs não são gerados se a solicitação da API não obtém uma resposta dentro do tempo limite da função do Lambda. Se a solicitação da API terminar devido ao tempo limite de uma função, tente uma das seguintes opções:

Alterar as configurações do AWS SDK

As configurações de contagem de novas tentativas e tempo limite do AWS SDK devem permitir tempo suficiente para que sua chamada da API receba uma resposta. Para determinar os valores corretos para cada configuração, teste configurações diferentes e obtenha as seguintes informações:

  • Tempo médio para estabelecer uma conexão bem-sucedida
  • Tempo médio de uma solicitação da API completa (até que ela seja retornada com sucesso)
  • Se novas tentativas devem ser feitas pelo AWS SDK ou código

Para mais informações sobre como alterar as configurações de contagem de novas tentativas e tempo limite, consulte a seguinte documentação de configuração do cliente do AWS SDK:

A seguir estão alguns exemplos de comandos que alteram a contagem de novas tentativas e as configurações de tempo limite para cada runtime.

Importante: Antes de usar qualquer um dos comandos a seguir, substitua os valores de exemplo de cada configuração pelos valores do seu caso de uso.

Exemplo de comando do Python (Boto 3) para alterar as configurações de contagem de novas tentativas e tempo limite

# max_attempts: retry count / read_timeout: socket timeout / connect_timeout: new connection timeout

from botocore.session import Session
from botocore.config import Config

s = Session()
c = s.create_client('s3', config=Config(connect_timeout=5, read_timeout=60, retries={'max_attempts': 2}))

Exemplo de comando do JavaScript/Node.js para alterar as configurações de contagem de novas tentativas e tempo limite

// maxRetries: retry count / timeout: socket timeout / connectTimeout: new connection timeout

var AWS = require('aws-sdk');

AWS.config.update({

    maxRetries: 2,

    httpOptions: {

        timeout: 30000,

        connectTimeout: 5000

    }

});

Exemplo de comando do Java para alterar as configurações de contagem de novas tentativas e tempo limite

// setMaxErrorRetry(): retry count / setSocketTimeout(): socket timeout / setConnectionTimeout(): new connection timeout

ClientConfiguration clientConfig = new ClientConfiguration();

clientConfig.setSocketTimeout(60000);
clientConfig.setConnectionTimeout(5000);
clientConfig.setMaxErrorRetry(2);

AmazonDynamoDBClient ddb = new AmazonDynamoDBClient(credentialsProvider,clientConfig);

Exemplo de comando do .NET para alterar as configurações de contagem de novas tentativas e tempo limite

// MaxErrorRetry: retry count / ReadWriteTimeout: socket timeout / Timeout: new connection timeout

var client = new AmazonS3Client(

    new AmazonS3Config {
        Timeout = TimeSpan.FromSeconds(5),
        ReadWriteTimeout = TimeSpan.FromSeconds(60),
        MaxErrorRetry = 2
});

Exemplo de comando do Go para alterar as configurações de contagem de novas tentativas

// Create Session with MaxRetry configuration to be shared by multiple service clients.
sess := session.Must(session.NewSession(&aws.Config{
    MaxRetries: aws.Int(3),
}))

// Create S3 service client with a specific Region.
svc := s3.New(sess, &aws.Config{
    Region: aws.String("us-west-2"),
})

Exemplo de comando do Go para alterar as configurações de tempo limite da solicitação

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// SQS ReceiveMessage
params := &sqs.ReceiveMessageInput{ ... }
req, resp := s.ReceiveMessageRequest(params)
req.HTTPRequest = req.HTTPRequest.WithContext(ctx)
err := req.Send()

(Opcional) Alterar a configuração de tempo limite da função do Lambda

Um tempo limite baixo da função do Lambda pode fazer com que conexões íntegras sejam interrompidas precocemente. Se isso estiver acontecendo em seu caso de uso, aumente a configuração de tempo limite da função para permitir tempo suficiente para que sua chamada da API receba uma resposta.

Use a fórmula a seguir para estimar o tempo base necessário para o tempo limite da função:

First attempt (connection timeout + socket timeout) + Number of retries x (connection timeout + socket timeout) + 20 seconds additional code runtime margin = Required Lambda function timeout

Exemplo de cálculo do tempo limite da função do Lambda

Observação: o cálculo a seguir é para um AWS SDK configurado para três novas tentativas, um tempo limite de conexão de 10 segundos e um tempo limite de soquete de 30 segundos.

First attempt (10 seconds + 30 seconds) + Number of retries [3 * (10 seconds + 30 seconds)] + 20 seconds additional code runtime margin = 180 seconds

Informações relacionadas

Invocar (referência da API do Lambda)

Tratamento de erros e novas tentativas automáticas no AWS Lambda

Cotas do Lambda

AWS OFICIAL
AWS OFICIALAtualizada há 3 anos