Come posso risolvere i problemi relativi ai tentativi e al timeout quando uso AWS SDK per invocare una funzione Lambda?

7 minuti di lettura
0

Quando invoco la mia funzione AWS Lambda con AWS SDK, la funzione si interrompe, la richiesta API non va a buon fine o un'azione API viene duplicata.

Breve descrizione

Potrebbero verificarsi problemi relativi ai tentativi e al timeout quando si invoca una funzione Lambda con AWS SDK a causa delle seguenti condizioni:

  • Un'API remota è irraggiungibile o impiega troppo tempo per rispondere a una chiamata API.
  • La chiamata API non riceve una risposta entro il timeout del socket.
  • La chiamata API non riceve una risposta entro il periodo di timeout della funzione Lambda.

Nota: Le chiamate API possono richiedere più tempo del previsto quando si verificano problemi di connessione di rete. I problemi di rete possono anche causare nuovi tentativi e richieste API duplicate. Per prepararti a questi eventi, assicurati che la tua funzione Lambda sia idempotente.

Se usi AWS SDK per effettare una chiamata API e la chiamata fallisce, l’AWS SDK riprova automaticamente a effettuare la chiamata. Il numero e la durata dei tentativi di AWS SDK dipendono da impostazioni che variano a seconda dell'AWS SDK.

Impostazioni predefinite per i tentativi di AWS SDK

Nota: Alcuni valori possono essere diversi per altri servizi AWS.

AWS SDKNumero massimo di tentativiTimeout della connessioneTimeout del socket
Python (Boto 3)dipende dal servizio60 secondi60 secondi
JavaScript/Node.jsdipende dal servizioN/A120 secondi
Java310 secondi50 secondi
.NET4100 secondi300 secondi
Go3N/AN/A

Per risolvere i problemi relativi ai tentativi e al timeout, innanzitutto esamina i log della chiamata API per individuare il problema. Quindi, modifica il numero di tentativi e le impostazioni di timeout dell'AWS SDK in base alle esigenze di ogni caso d'uso. Per concedere un tempo sufficiente per una risposta alla chiamata API, aggiungi del tempo all'impostazione di timeout della funzione Lambda.

Soluzione

Registra le chiamate API effettuate dall'AWS SDK

Usa Amazon CloudWatch Logs per ottenere dettagli sulle connessioni non riuscite e sul numero di tentativi per ciascuna di esse. Per ulteriori informazioni, consulta Using CloudWatch Logs logs with Lambda. In alternativa, consulta le seguenti istruzioni per l'AWS SDK che hai utilizzato:

Esempio di log degli errori in cui la chiamata API non è riuscita a stabilire una connessione (timeout della connessione)

START RequestId: b81e56a9-90e0-11e8-bfa8-b9f44c99e76d Version: $LATEST2018-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

...

Esempio di log degli errori in cui la connessione alla chiamata API ha avuto esito positivo, ma è scaduta dopo che la risposta dell'API ha richiesto troppo tempo (timeout del socket)

START RequestId: 3c0523f4-9650-11e8-bd98-0df3c5cf9bd8 Version: $LATEST2018-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

Nota: Questi log non vengono generati se la richiesta API non riceve una risposta entro il timeout della funzione Lambda. Se la richiesta API termina a causa di un timeout di una funzione, prova una delle seguenti opzioni:

Modifica le impostazioni dell'AWS SDK

Le impostazioni relative al numero di tentativi eal timeout dell'AWS SDK dovrebbero consentire alla chiamata API un tempo sufficiente per ottenere una risposta. Per determinare i valori corretti per ogni impostazione, prova diverse configurazioni e ottieni le seguenti informazioni:

  • Tempo medio necessario per stabilire una connessione riuscita
  • Tempo medio impiegato da una richiesta API completa fino a quando non viene restituita correttamente

Per ulteriori informazioni sulla modifica del numero di tentativi e delle impostazioni di timeout, consulta la seguente documentazione sulla configurazione del client AWS SDK:

Di seguito sono riportati alcuni comandi di esempio che modificano il numero di tentativi e le impostazioni di timeout per ogni runtime.

Nota: assicurati di sostituire i valori di esempio per ogni impostazione con i valori per il tuo caso d'uso.

Esempio di comando Python (Boto 3) per modificare il numero di tentativi e le impostazioni di timeout

# 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}))

Esempio di comando JavaScript/Node.js per modificare il numero di tentativi e le impostazioni di timeout

// 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

    }

});

Esempio di comando JavaScript V3 per modificare il numero di tentativi e le impostazioni di timeout

const { S3Client, ListBucketsCommand } = require("@aws-sdk/client-s3");
const { NodeHttpHandler } = require("@aws-sdk/node-http-handler");
const client = new S3Client({
    requestHandler: new NodeHttpHandler({
        connectionTimeout: 30000,
        socketTimeout: 50000
    }),
    maxAttempts: 2
});

Esempio di comando Java per modificare il numero di tentativi e le impostazioni di timeout

// 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);

Esempio di comando.NET per modificare il numero di tentativi e le impostazioni di timeout

// 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
});

Esempio di comando Go per modificare le impostazioni relative al numero di tentativi

// 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"),
})

Esempio di comando Go per modificare le impostazioni di timeout delle richieste

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()

(Facoltativo) Modifica l'impostazione di timeout della funzione Lambda

Un timeout della funzione Lambda limitato può causare l'interruzione anticipata delle connessioni stabili. Aumenta l'impostazione del timeout della funzione per concedere un tempo sufficiente alla chiamata API per ottenere una risposta.

Utilizza la seguente formula per stimare il tempo base necessario per il timeout della funzione:

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

Esempio di calcolo del timeout della funzione Lambda

Nota: Il calcolo seguente si riferisce a un AWS SDK configurato per tre tentativi, un timeout di connessione di 10 secondi e un timeout del socket di 30 secondi.

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

Informazioni correlate

Invoke

Understanding retry behavior in Lambda

Lambda quotas

AWS UFFICIALE
AWS UFFICIALEAggiornata 5 mesi fa