Comment résoudre les problèmes de nouvelles tentatives et de délai d'expiration lors de l'appel d'une fonction Lambda à l'aide d'un kit SDK AWS ?

Lecture de 7 minute(s)
0

Lorsque j'appelle ma fonction AWS Lambda à l'aide d'un kit SDK AWS, la fonction expire, la demande d'API cesse de répondre ou une action d'API est dupliquée. Comment résoudre ces erreurs ?

Brève description

Trois raisons permettent d'expliquer pourquoi des problèmes de nouvelles tentatives et de délai d'expiration se produisent lors de l'appel d'une fonction Lambda à l'aide d'un kit SDK AWS :

  • Une API distante est injoignable 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 d'expiration du socket.
  • L'appel d'API n'obtient pas de réponse dans le délai d'expiration de 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 demandes d'API en double. Pour vous préparer à ces éventualités, assurez-vous que votre fonction Lambda est idempotente.

Si vous effectuez un appel d'API à l'aide d'un kit SDK AWS et que l'appel échoue, le kit SDK AWS retente automatiquement l'appel. Le nombre de tentatives du kit SDK AWS et leur durée sont déterminés par des paramètres qui varient d'un kit SDK AWS à l'autre.

Paramètres de nouvelles tentatives par défaut du kit SDK AWS

Remarque : certaines valeurs peuvent varier d'un service AWS à l'autre.

KIT SDK AWSNombre maximal de nouvelles tentativesDélai d'expiration de la 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 de nouvelles tentatives et de délai d'expiration, commencez par examiner les journaux de l'appel d'API afin d'identifier le problème. Ensuite, modifiez les paramètres de nombre de tentatives et de délai d'expiration du kit SDK AWS en fonction des besoins de chaque cas d'utilisation. Pour laisser suffisamment de temps pour obtenir une réponse à l'appel API, ajoutez du temps au paramètre de délai d'expiration de la fonction Lambda.

Résolution

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

Utilisez Amazon CloudWatch Logs pour obtenir des détails sur les connexions échouées et le nombre de nouvelles tentatives effectuées pour chacune d'entre elles. Pour plus d'informations, consultez Accès aux journaux Amazon CloudWatch Logs pour AWS Lambda. Vous pouvez également consulter les instructions relatives au kit SDK AWS que vous utilisez :

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

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

...

Exemple de journal d'erreurs où la connexion à l'appel API a réussi, mais a expiré après une attente trop longue de la réponse API (délai d'expiration du 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

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

Modifiez les paramètres du kit SDK AWS

Les paramètres de nombre de tentatives et de délai d'expiration du kit SDK AWS doivent prévoir un temps suffisant pour que votre appel d'API obtienne une réponse. Afin de déterminer les bonnes valeurs pour chaque paramètre, testez différentes configurations et obtenez les informations suivantes :

  • Temps moyen pour établir une connexion réussie
  • Durée moyenne d'une demande d'API complète (jusqu'à obtention d'une réponse correcte)
  • Si les tentatives doivent être effectuées par le kit SDK AWS ou par le code

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 du client SDK AWS :

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

Important : avant d'utiliser les commandes suivantes, remplacez les exemples de valeurs de chaque paramètre par les valeurs de votre cas d'utilisation.

Exemple de commande Python (Boto 3) permettant de 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 permettant de 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 Java permettant de 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 permettant de 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 Commande Go permettant de 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 permettant de modifier les paramètres de délai d'expiration d'une demande

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) Modifiez le paramètre de délai d'expiration de votre fonction Lambda

Un délai d'expiration court pour la fonction Lambda peut entraîner la suppression précoce de connexions saines. Si cela se produit dans votre cas d'utilisation, augmentez le délai d'expiration de la fonction afin de laisser suffisamment de temps pour que votre appel d'API obtienne 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 d'une fonction Lambda

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

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

Informations connexes

Appeler (Référence d'API Lambda)

Gestion des erreurs et nouvelles tentatives automatiques dans AWS Lambda

Quotas Lambda

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 2 ans