Comment puis-je résoudre les problèmes liés aux nouvelles tentatives et au délai d'expiration lorsque j’utilise un kit SDK AWS pour invoquer une fonction Lambda ?

Lecture de 7 minute(s)
0

Lorsque j'invoque ma fonction AWS Lambda à l'aide du kit SDK AWS, la fonction expire, la requête d'API échoue ou une action d'API est dupliquée.

Brève description

Des problèmes de nouvelle tentative et de délai d'expiration peuvent survenir lors de l'invocation d'une fonction Lambda avec un kit SDK AWS en raison des conditions suivantes :

  • Une API distante est inaccessible ou met trop de temps à répondre à un appel d'API.
  • L'appel d'API n'obtient pas de réponse dans le délai imparti au socket.
  • L'appel d'API n'obtient pas de réponse dans le délai imparti à la fonction Lambda.

Remarque : Les appels d'API peuvent prendre plus de temps que prévu lorsque des problèmes de connexion réseau surviennent. Les problèmes de réseau peuvent également entraîner de nouvelles tentatives et des requêtes d'API dupliquées. Pour vous préparer à ces occurrences, assurez-vous que votre fonction Lambda est idempotente.

Si vous utilisez un kit SDK AWS pour effectuer un appel d'API et que l'appel échoue, le kit SDK AWS réitère automatiquement l'appel. Le nombre de nouvelles tentatives du kit SDK AWS et leur durée sont déterminés par les paramètres qui varient d'un kit SDK AWS à un autre.

Paramètres de nouvelle tentative par défaut du kit SDK AWS

Remarque : Certaines valeurs peuvent être différentes pour d'autres services AWS.

Kit SDK AWSNombre maximal de nouvelles tentativesDélai de connexionDélai d'expiration du socket
Python (Boto 3)dépend du service60 secondes60 secondes
JavaScript/Node.jsdépend du serviceN/A120 secondes
Java310 secondes50 secondes
.NET4100 secondes300 secondes
Go3N/AN/A

Pour résoudre les problèmes liés aux nouvelles tentatives et au délai d'expiration, commencez par consulter les journaux de l'appel d'API pour identifier le problème. Puis, modifiez les paramètres de nombre de nouvelles tentatives et de délai d’expiration du SDK AWS si nécessaire pour chaque cas d'utilisation. Pour prévoir suffisamment de temps afin d’obtenir une réponse à l'appel d'API, augmentez le temps pour le paramètre de délai d'attente de la fonction Lambda.

Résolution

Enregistrer les appels d'API effectués par le kit SDK AWS

Utilisez Amazon CloudWatch Logs pour obtenir des informations sur les échecs de connexion et le nombre de nouvelles tentatives pour chacune d'entre elles. Pour plus d'informations, consultez la section Utilisation des journaux CloudWatch Logs avec Lambda. Vous pouvez également consulter les instructions suivantes pour le kit SDK AWS que vous avez utilisé :

Exemple de journal des erreurs dans lequel l'appel d'API n'a pas réussi à établir une connexion (délai de connexion)

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

...

Exemple de journal des erreurs dans lequel la connexion à l'appel d'API a réussi, mais a expiré car la réponse de l'API a pris trop de temps (délai d'expiration du 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

Remarque : Ces journaux ne sont pas générés si la requête d'API n'obtient pas de réponse dans le délai d'expiration de votre fonction Lambda. Si la requête d'API se termine en raison d'un délai d'expiration de la fonction, essayez l'une des solutions suivantes :

Modifier les paramètres du kit SDK AWS

Les paramètres de nombre de nouvelles tentatives et de délai d'expiration du KIT SDK AWS devraient prévoir suffisamment de temps pour que votre appel d'API obtienne une réponse. Pour déterminer les valeurs adéquates pour chaque paramètre, testez différentes configurations et obtenez les informations suivantes :

  • Durée moyenne nécessaire à l’établissement d’une connexion réussie
  • Durée moyenne d'une requête d'API complète (jusqu'à ce qu'elle soit renvoyée avec succès)

Pour plus d'informations sur la modification des paramètres de nombre de nouvelles tentatives et de délai d'expiration, consultez la documentation de configuration client du kit SDK AWS suivante :

Voici quelques exemples de commandes qui modifient les paramètres de nombre de nouvelles tentatives et de délai d'expiration pour chaque exécution.

Remarque : Veillez à remplacer les valeurs d'exemple pour chaque paramètre par les valeurs correspondant à votre cas d'utilisation.

Exemple de commande Python (Boto 3) pour modifier les paramètres de nombre de nouvelles tentatives et de délai d'expiration

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

Exemple de commande JavaScript/Node.js pour modifier les paramètres de nombre de nouvelles tentatives et de délai d’expiration

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

    }

});

Exemple de commande JavaScript V3 pour modifier les paramètres de nombre de nouvelles tentatives et de délai d’expiration

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

Exemple de commande Java pour modifier les paramètres de nombre de nouvelles tentatives et de délai d’expiration

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

Exemple de commande .NET pour modifier les paramètres de nombre de nouvelles tentatives et de délai d’expiration

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

Exemple de commande Go pour modifier les paramètres de nombre de nouvelles tentatives

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

Exemple de commande Go pour modifier les paramètres de délai d'expiration des requêtes

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

(Facultatif) Modifier le paramètre de délai d'expiration de votre fonction Lambda

Une valeur basse de délai d'expiration de la fonction Lambda peut entraîner l'interruption anticipée des connexions saines. Augmentez le paramètre de délai d'expiration de la fonction pour laisser suffisamment de temps à votre appel d'API pour obtenir une réponse.

Utilisez la formule suivante pour estimer le temps de base nécessaire au délai d'expiration de la fonction :

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

Exemple de calcul du délai d'expiration de la fonction Lambda

Remarque : Le calcul suivant concerne un kit SDK AWS configuré pour trois nouvelles tentatives, un délai de connexion de 10 secondes et un délai d'expiration du socket de 30 secondes.

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

Informations connexes

Invoquer

Comprendre le comportement de nouvelle tentative dans Lambda

Quotas Lambda

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 4 mois