Como soluciono problemas de repetição e tempo limite ao invocar uma função do Lambda usando um AWS SDK?
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 SDK | Contagem máxima de novas tentativas | Tempo limite de conexão | Tempo limite do soquete |
Python (Boto 3) | depende do serviço | 60 segundos | 60 segundos |
JavaScript/Node.js | depende do serviço | N/A | 120 segundos |
Java | 3 | 10 segundos | 50 segundos |
.NET | 4 | 100 segundos | 300 segundos |
Go | 3 | N/A | N/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:
- Log de funções do AWS Lambda no Python
- Log de chamadas do AWS SDK para JavaScript
- Log de chamadas do AWS SDK para Java
- Log com o AWS SDK para .NET
- Log de chamadas de serviço (AWS SDK para Go)
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:
- Altere as configurações de nova tentativa no SDK para que todas as novas tentativas sejam feitas dentro do tempo limite.
- Aumente temporariamente a configuração de tempo limite da função do Lambda para permitir tempo suficiente para gerar logs do SDK.
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
Conteúdo relevante
- AWS OFICIALAtualizada há um ano
- AWS OFICIALAtualizada há 2 anos
- AWS OFICIALAtualizada há 2 anos