web-dev-qa-db-ja.com

SQS Lambda-ロジックを再試行しますか?

メッセージがSQSキューに追加され、ラムダ関数(nodejs)をトリガーするように構成されている場合。

ラムダ関数がトリガーされると、キューからメッセージを削除せずに5分後に同じメッセージを再試行したい場合があります。 Lambdaが外部ホスト(例:API)に接続できなかった場合にこれを行う理由-5分後に3回だけ再試行したい.

ノードjsでどのように記述できますか?

たとえば、Laravelでは、Specifying Max Job Attempts機能を使用できます。 public $tries = 5;を使用してジョブを試行できる回数

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

Node.jsで同様の方法を実行するにはどうすればよいですか?

メッセージを別のキューに追加することを考えています(再試行のため)。ラムダ関数は、5分後にそのキューからすべてのメッセージを読み取り、そのメッセージをメインキューに送り返すと、ラムダ関数がトリガーされます。

9
I'll-Be-Back

これが私がやった方法です。

  1. 通常のキュー(即時配信)の作成、Q1
  2. 遅延キューの作成(5分遅延)、Q2
  3. DLQの作成(再試行後)、DLQ1

(Q1/Q2)SQSトリガー-> Lambda L1(失敗した場合、(Q1/Q2)で削除し、Q2でドロップします)->失敗時DLQ

メッセージがQ1に到着すると、そこから成功した場合、Lambda L1がトリガーされます。失敗した場合、Q2(遅延キュー)にドロップします。 Q2に到着するすべてのメッセージには5分の遅延があります。

最初のメッセージに5分の遅延がある場合、2つのキューは必要ないかもしれません。 1つのキューが良いはずです。最初の遅延が許容できない場合、2つのキューが必要です。キューが2つあるもう1つの理由は、パスに到着する新しいメッセージを常に確保できることです。

Q1/Q2の処理でコード障害が発生した場合、awsインフラストラクチャはDLQ1に送信する前に3回すぐに再試行します。コードのエラーを処理すると、言及したタイミングでパイプラインを動作させることができます。

SQS遅延キュー:

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

SQS Lambdaアーキテクチャ:

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

enter image description here 役に立てば幸いです。

4
Kannaiyan

再試行と再試行の「タイムアウト」はすべてSQSキューで直接構成できます。

キューを作成するときに、次の属性を設定します。

SQS Queue Attributes

Default Visibility Timeoutは、受信したメッセージがhiddenになる時間ですあなたの申請。ラムダの実行中にメッセージが失敗し、例外がスローされた場合、ラムダはバッチ内のメッセージを削除せず、すべてのメッセージは最終的に再実行されます-キューに表示されます。

3回だけ試してみたい場合は、SQS再駆動ポリシー(別名Dead Letter Queue)を設定する必要があります

Dead Letter Queue Settings

再ドライブポリシーを使用すると、キューにメッセージが再表示された後、N回数(Nは1からおよび1000。

Lambdaが失敗したメッセージ(コード内で例外を生成するメッセージ)を処理し続けることを理解することが不可欠です:

  1. エラーなしで処理されます(ラムダはメッセージを削除します)
  2. Message Retention Period期限切れ(SQSはメッセージを削除します)
  3. SQSキューの再駆動ポリシーに設定されているDLQに送信されます(SQSはメッセージをDLQに「移動」します)
  4. コードでキューからメッセージを直接削除します(ユーザーがメッセージを削除します)

それ以外の場合、Lambdaはこの悪いメッセージを破棄しません。


重要な観察

Lambdaは失敗したメッセージを処理しません

SQS統合の動作を理解するために実行したいくつかの実験に基づいて(再試行の documentation はあいまいなATMです)、lambdaは失敗したメッセージを削除せず、引き続き再試行します。 Lambda DLQがセットアップされている場合でも、メッセージはDLQに送信されません。この目的のために lambda DLQ documentation で述べられているように、SQSキューの構成に完全に依存しています。

推奨:

  • SQSキューで再ドライブポリシーを常に使用します。

例外はメッセージのバッチ全体に失敗します

前に述べたように、メッセージの処理中にコードに例外がある場合、メッセージのバッチ全体が再試行されます。メッセージの一部が正しく処理されたかどうかは関係ありません。何らかの理由でダウンストリームサービスが失敗している場合、DLQで処理されたメッセージが表示される場合があります。

推奨:

  • 正しく処理されたメッセージを手動で削除する
  • ラムダ関数が同じメッセージを複数回処理できることを確認してください

ラムダ同時実行制限とSQS副作用

ブログの投稿「 Lambda同時実行制限とSQSトリガーがうまく混合しない(時々) 」では、同時実行制限の設定が低すぎると、ラムダによってメッセージのバッチが抑制され、受信された試行は、処理されることなくインクリメントされます。

推奨:

投稿とAmazonの推奨事項は次のとおりです。

  • キューの可視性タイムアウトを、機能で構成するタイムアウトの少なくとも6倍に設定します。
  • 余分な時間により、関数が前のバッチを処理している間に関数の実行が抑制された場合、Lambdaが再試行できるようになります。
  • キューの再ドライブポリシーのmaxReceiveCountを少なくとも5に設定します。これにより、スロットルによる配信不能キューへのメッセージ送信を回避できます。
  • 失敗したメッセージを十分に長く保持して、後で再処理するためにそれらを戻すことができるように、配信不能レターを構成します。
12
Onema

非常にシンプルで、コーディングを行う必要はありません。まず、コードがエラーをスローする場合、AWS Lambdaはさらに3回再試行してコードを実行します。この場合、外部APIにアクセスできなかった場合、AWSが3回目に再試行するまでに大きな変更があります。APIは機能します。さらに、再試行間の遅延はランダムな意味であり、再試行間に遅延があります。

最悪の事態が発生し、外部APIがまだ起動していない場合は、各ラムダが持つデッドレターキュー(DLQ)機能を利用できます。これにより、SQSに問題の内容を伝えるメッセージがプッシュされるため、追加のアクションを実行できます。この場合、作成するまで再試行を続けてください。

詳細はこちらをご覧ください: https://docs.aws.Amazon.com/lambda/latest/dg/dlq.html

1
David Gatti

このブログによると:

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

既存の再試行ロジックとデッドレターキューを活用します。 Lambda関数が成功を返さない場合、メッセージはキューから削除されず、可視性タイムアウトの期限が切れた後に再表示されます。

1
Spiff