Come posso risolvere i problemi relativi ai tentativi e ai timeout quando richiamo una funzione Lambda utilizzando un AWS SDK?

7 minuti di lettura
0

Quando richiamo la mia funzione AWS Lambda utilizzando un AWS SDK la funzione si interrompe, la richiesta API smette di rispondere o un'azione API viene duplicata. Come posso risolvere questi problemi?

Breve descrizione

Ci sono tre motivi per cui si verificano problemi di nuovi tentativi e di timeout quando si richiama una funzione Lambda con un AWS SDK:

  • 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 effettui una chiamata API utilizzando un AWS SDK e la chiamata fallisce, l’AWS SDK riprova automaticamente ad effettuare la chiamata. Il numero di tentativi dell'AWS SDK e per quanto tempo si prova dipende dalle impostazioni specifiche di quell'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 i file di log Amazon CloudWatch per ottenere dettagli sulle connessioni non riuscite e sul numero di tentativi per ciascuna di esse. Per ulteriori informazioni, consulta Accesso ai log di Amazon CloudWatch per AWS Lambda. In alternativa, consulta le seguenti istruzioni per l'AWS SDK che stai utilizzando:

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: $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

...

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: $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

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 con successo)
  • Se è necessario eseguire nuovi tentativi tramite l'SDK o il codice AWS

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.

Importante: Prima di utilizzare uno dei seguenti comandi, sostituisci 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 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. Se questo è il tuo caso d'uso, aumenta l'impostazione del timeout della funzione per consentire alla chiamata API di 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

Richiama (riferimento API Lambda)

Gestione degli errori e tentativi automatici in AWS Lambda

Quote Lambda

AWS UFFICIALE
AWS UFFICIALEAggiornata 3 anni fa