web-dev-qa-db-fra.com

SQS Lambda - logique de nouvelle tentative?

Lorsque le message a été ajouté à une file d'attente SQS et qu'il est configuré pour déclencher une fonction lambda (nodejs).

Lorsqu'une fonction lambda est déclenchée - je peux vouloir réessayer le même message après 5 minutes sans supprimer le message de la file d'attente. La raison pour laquelle je veux faire cela si Lambda ne pouvait pas se connecter à un hôte externe (par exemple: API) - j'aime réessayer après 5 minutes pour 3 tentatives seulement.

Comment cela peut-il être écrit dans le nœud js?

Par exemple à Laravel, nous pouvons Specifying Max Job Attempts Fonctionnalité. Nombre de tentatives d'exécution du travail à l'aide de public $tries = 5;

Source: https://laravel.com/docs/5.7/queues#max-job-attempts-and-timeout

Comment pouvons-nous faire de la même façon dans node.js?

Je pense ajouter un message à une autre file d'attente (pour réessayer). Une fonction lambda lit tous les messages de cette file d'attente après 5 minutes et renvoie ce message à la file d'attente principale et elle déclenche une fonction lambda.

9
I'll-Be-Back

Voici comment je l'ai fait.

  1. Créer des files d'attente normales (livraison immédiate), T1
  2. Créer des files d'attente de retard (5 minutes de retard), Q2
  3. Créer DLQ (après de nouvelles tentatives), DLQ1

(Q1/Q2) SQS Trigger -> Lambda L1 (en cas d'échec, supprimez-le sur (Q1/Q2), supprimez-le sur Q2) -> On Failure DLQ

Lorsque les messages arrivent sur Q1, il déclenche Lambda L1 si le succès s'en suit. En cas d'échec, déposez-le sur Q2 (qui est une file d'attente retardée). Chaque message qui arrive sur Q2 aura un délai de 5 minutes.

Si votre message initial peut avoir un délai de 5 minutes, vous n'aurez peut-être pas besoin de deux files d'attente. Une file d'attente devrait être bonne. Si le délai initial n'est pas acceptable, vous avez besoin de deux files d'attente. Une autre raison d'avoir deux files d'attente, vous aurez toujours un moyen pour les nouveaux messages qui arrivent sur le chemin.

Si vous rencontrez une erreur de code dans la gestion de l'infrastructure aws Q1/Q2, réessayez immédiatement 3 fois avant de l'envoyer à DLQ1. Si vous gérez l'erreur dans le code, vous pouvez faire fonctionner le pipeline avec les horaires que vous avez mentionnés.

Files d'attente de délai SQS:

https://docs.aws.Amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-delay-queues.html

Architecture SQS Lambda:

https://nordcloud.com/Amazon-sqs-as-a-lambda-event-source/

enter image description here J'espère que ça aide.

4
Kannaiyan

Les tentatives et les tentatives de "délai d'expiration" peuvent toutes être configurées directement dans la file d'attente SQS.

Lorsque vous créez une file d'attente, configurez les attributs suivants:

SQS Queue Attributes

Le Délai de visibilité par défaut sera l'heure à laquelle le message sera masqué une fois qu'il aura été reçu par votre application. Si le message échoue pendant l'exécution de lambda et qu'une exception est levée, lambda ne supprimera aucun des messages du lot et tous finiront par -apparaître dans la file d'attente.

Si vous ne voulez essayer que 3 fois, vous devez définir la politique de ré-entraînement SQS (AKA Dead Letter Queue)

Dead Letter Queue Settings

La stratégie de re-drive permettra à votre file d'attente de rediriger les messages vers une file d'attente de lettres mortes (DLQ) après que le message est réapparu dans la file d'attente N nombre de fois, où N est un nombre entre 1 et 1000.

Il est essentiel de comprendre que lambda continuera de traiter un message ayant échoué (un message qui génère une exception dans le code) jusqu'à ce que:

  1. Il est traité sans aucune erreur (lambda supprime le message)
  2. Le Message Retention Period expire (SQS supprime le message)
  3. Il est envoyé à l'ensemble DLQ dans la politique de ré-entraînement de la file d'attente SQS (SQS "déplace" le message vers le DLQ)
  4. Vous supprimez le message de la file d'attente directement dans votre code (l'utilisateur supprime le message)

Sinon, Lambda ne disposera pas de ce mauvais message.


Observations importantes

Lambda ne traitera pas les messages ayant échoué

Sur la base de plusieurs expériences que j'ai exécutées pour comprendre le comportement de l'intégration SQS (la documentation lors des nouvelles tentatives est un ATM ambigu), lambda ne supprimera pas les messages ayant échoué et continuera à les réessayer. Même si une Lambda DLQ est configurée, les messages ne seront pas envoyés à la DLQ, elle dépend entièrement de la configuration de la file d'attente SQS à cet effet, comme indiqué dans la documentation lambda DLQ .

Recommandation:

  • Utilisez toujours une stratégie de ré-entraînement dans votre file d'attente SQS.

Les exceptions échoueront à tout un lot de messages

Comme je l'ai indiqué plus tôt s'il y a une exception dans votre code lors du traitement d'un message, le lot entier de messages est réessayé, peu importe si certains des messages ont été traités correctement. Si, pour une raison quelconque, un service en aval échoue, vous pouvez vous retrouver avec des messages qui ont été traités dans le DLQ.

Recommandation:

  • Supprimez manuellement les messages qui ont été traités correctement
  • Assurez-vous que votre fonction lambda peut traiter le même message plusieurs fois

Limites de concurrence lambda et effets secondaires SQS

Le billet de blog " Lambda Concurrency Limits and SQS Triggers Don't Mix Well Well (Parfois) " décrit comment, si votre limite de concurrence est définie trop bas, lambda peut provoquer la limitation de lots de messages et le = tentative reçue à incrémenter sans jamais être traité.

Recommandation:

Le message et les recommandations d'Amazon sont les suivants:

  • Définissez le délai d'expiration de la visibilité de la file d'attente sur au moins 6 fois le délai d'expiration que vous configurez sur votre fonction.
  • Le temps supplémentaire permet à Lambda de réessayer si l'exécution de votre fonction est limitée pendant que votre fonction traite un lot précédent.
  • Définissez le maxReceiveCount sur la stratégie de re-lecteur de la file d'attente sur au moins 5. Cela permettra d'éviter d'envoyer des messages à la file d'attente de lettres mortes en raison de la limitation.
  • Configurez la lettre morte pour conserver les messages ayant échoué suffisamment longtemps pour pouvoir les reculer ultérieurement pour les retraiter
12
Onema

Assez simple et sans avoir besoin de faire de codage. Tout d'abord: si votre code génère une erreur, AWS Lambda réessayera 3 fois de plus pour exécuter votre code. Dans ce cas, si l'API externe n'était pas accessible, il y a un grand changement qui, la troisième fois qu'AWS réessaie - l'API fonctionnera. De plus, le délai entre les essais est aléatoire, ce qui signifie qu'il y a un délai entre les essais.

Si le pire se produit et que l'API externe n'est pas encore active, vous pouvez profiter de la fonction de file d'attente de lettres mortes (DLQ) de chaque lambda. Ce qui poussera vers SQS un message indiquant ce qui n'a pas fonctionné, afin que vous puissiez prendre des mesures supplémentaires. Dans ce cas, continuez d'essayer jusqu'à ce que vous y arriviez.

Vous pouvez en savoir plus ici: https://docs.aws.Amazon.com/lambda/latest/dg/dlq.html

1
David Gatti

Selon ce blog:

https://www.lucidchart.com/blog/cloud/5-reasons-why-sqs-lambda-triggers-are-a-big-deal

Tirez parti de la logique de nouvelle tentative et des files d'attente de lettres mortes. Si la fonction Lambda ne renvoie pas de succès, le message ne sera pas supprimé de la file d'attente et réapparaîtra après l'expiration du délai de visibilité.

1
Spiff