web-dev-qa-db-fra.com

AWS Lambda - Comment arrêter les tentatives en cas d'échec

Je sais que lorsqu'une fonction Lambda échoue (par exemple, lorsqu'il y a un délai d'attente), elle essaie d'exécuter la fonction 3 fois de plus. Y a-t-il un moyen d'éviter ce comportement? J'ai lu la documentation, mais je n'ai rien trouvé à ce sujet.

Merci!

16
AleGallagher

Il n’existe pas de moyen de désactiver le comportement de réessai des fonctions Lambda.

Je suggère deux options pour régler ce problème:

  1. Permettez à votre Lambda de gérer correctement les tentatives de relance. Vous pouvez utiliser context.AwsRequestId (ou le champ correspondant) qui sera identique lors de la prochaine tentative Lambda.
  2. Placez votre Lambda dans une machine à états (à l'aide de AWS Step Functions). Vous ne pouvez alors désactiver les tentatives.

Ce blog J'ai écrit donne une explication plus générale.

12
Ronyis

Il réessaye quand il s’agit d’un échec non géré (une erreur que vous n’avez pas interceptée) ou si vous l’avez géré mais avez toujours demandé à Lambda de réessayer (par exemple, dans Nœud, lorsque vous appelez callback() avec un premier argument non nul).

Pour l'empêcher de réessayer, assurez-vous que toute erreur est gérée et dites à Lambda que votre appel s'est terminé avec succès en renvoyant une erreur (ou dans Node, en appelant callback(null, <any>).

Pour ce faire, vous pouvez inclure tout le corps de votre fonction de gestionnaire avec un try-catch.

module.exports.handler(event, context, callback) {
  try {
    // Do you what you want to do.
    return callback(null, 'Success')
  } catch (err) {
    // You probably still want to log it.
    console.error(err)
    // Return happy despite all the hardships you went through.
    return callback(null, 'Still success')
  }
}

En ce qui concerne les échecs dus aux délais d'attente, vous pouvez faire certaines choses.

Si le délai expire en dehors de votre gestionnaire, il y a généralement un problème avec votre code (par exemple, une configuration de base de données incorrecte, etc.) que vous devriez examiner.

Si le délai expire à l'intérieur votre gestionnaire lors d'une invocation, vous pouvez y remédier.

  • S'il s'agit d'une requête HTTP, vous devez définir un délai d'attente plus court que celui de votre Lambda. Ainsi, la requête échouera correctement et vous pourrez le récupérer.
  • S'il s'agit d'une connexion à une base de données, vous pouvez probablement définir un délai d'expiration à l'aide de la bibliothèque que vous utilisez.
  • Si c'est votre logique qui expire, vous pouvez mettre à niveau le Lambda afin qu'il utilise davantage de mémoire CPU pour le rendre plus rapide. Vous pouvez également vérifier context.getRemainingTimeInMillis() pour savoir si le Lambda est sur le point d'expirer, afin de pouvoir le gérer plus tôt.
19
dashmug

Utilisez le code ci-dessous pour identifier et arrêter les tentatives en cas d’échec.

  exports.handler = (event, context, callback) => {
      context.callbackWaitsForEmptyEventLoop = false;
      let lastReqId;
      if (lastReqId == context.awsRequestId) {
        console.log("Lambda auto retry detected. Aborting");// you can write your own logic to decide what to do with the failure data
        return context.succeed();
      } else {
        console.log("new context");
        lastReqId = context.awsRequestId;
      }
    };

vous pouvez en lire plus à ce sujet ici

0
Kshitiz Jaiswal

Si vous utilisez python, vous devez également placer le code dans le bloc try/catch, mais il n'y aura pas de rappel. Par exemple:

try:
    do_something()
except Exception as e:
    print('Error: ' + str(e))

Puisque l'erreur a été gérée, Lambda ne réessayera pas.

0
Raptor