Come posso risolvere i problemi relativi ai tentativi e ai timeout quando richiamo una funzione Lambda utilizzando un AWS SDK?
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 SDK | Numero massimo di tentativi | Timeout della connessione | Timeout del socket |
Python (Boto 3) | dipende dal servizio | 60 secondi | 60 secondi |
JavaScript/Node.js | dipende dal servizio | N/A | 120 secondi |
Java | 3 | 10 secondi | 50 secondi |
.NET | 4 | 100 secondi | 300 secondi |
Go | 3 | N/A | N/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:
- Registrazione della funzione AWS Lambda in Python
- Registrazione dell'AWS SDK per le chiamate JavaScript
- Registrazione dell'AWS SDK per le chiamate Java
- Registrazione con l'AWS SDK per .NET
- Registrazione delle chiamate di servizio (AWS SDK per Go)
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 dei tentativi nell'SDK in modo che tutti i tentativi vengano eseguiti entro il limite di timeout.
- Aumenta l'impostazione del timeout della funzione Lambda temporaneamente per concedere tempo sufficiente per generare i log SDK.
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)
Contenuto pertinente
- AWS UFFICIALEAggiornata un anno fa
- AWS UFFICIALEAggiornata un anno fa
- AWS UFFICIALEAggiornata un anno fa