Lambda 和 SQS 触发器在 15 次迭代后停止

问题描述 投票:0回答:1

我有一个 aws lambda 函数。它将使用 SQS 触发。 lambda 时间为 15 分钟,SQS 队列可见时间为 16 分钟。当 lambda 即将超时时,我将在同一个队列中放入一个延续键并结束 lambda 的当前实例。 lambda 的新实例将使用 SQS 消息从它停止的位置开始。一切都工作正常,直到 lambda 第 16 次向 SQS 发送消息(执行)。

SQS 队列显示消息正在传输中,但 lambda 没有接收消息。 10 次重试后,消息将被推送到 DLQ。此外,不存在并发问题。我的 lambda 在执行 15 次后没有选择 SQS 消息的原因是什么?

我使用 lambda 和 SQS 已有 4 年多了,但从未遇到过这样的事情。不知道我错过了什么。

编辑: SQS 中的消息保留时间为 4 天。 您可以执行以下操作来重现此问题。创建一个名为 test-sqs 的 sqs,可见性时间为 30 秒,并将其作为触发器添加到新的 lambda(lambda 超时为 20 秒)。同时添加一个dlq到sqs队列中。以下是 lambda 代码。

import json
import boto3
import time
from datetime import datetime
sqsClient = boto3.client('sqs')
SQS_URL = "https://sqs.ap-south-1.amazonaws.com/YOUR_ACCOUNT_NUMBER/test-sqs"
def lambda_handler(event, context):
    if ("Records" in event) and (len(event["Records"]) > 0):
        print("Trigger through SQS.")
        for record in event["Records"]:
            event = json.loads(record["body"])
    else:
        print("Triggered manually.")
    print(event)
    start_time = datetime.utcnow()
    print("start", start_time)
    time.sleep(1)
    segment_number = 1
    if "segment_number" in event:
        segment_number = event["segment_number"]

    if segment_number <= 20:
        segment_number += 1
        payload = {
            "segment_number" : segment_number
        }
        sqsClient.send_message(QueueUrl = SQS_URL, MessageBody=json.dumps(payload))
    else:
        print("COMPLETED")
    print("end", datetime.utcnow())
python amazon-web-services aws-lambda amazon-sqs
1个回答
0
投票

SQS和Lambda具有递归检测机制。如果它识别出消息正在进入无限循环,那么它会停止执行。截至目前,该案已于第16次处决时停止。这就是您的 Lambda 仅运行 15 次的原因。

当失败时,它将超出其最大接收计数并将消息添加到DLQ。它发出

RecursiveInvocationsDropped
Cloudwatch 指标。

有关更多信息,请参阅此处的文章:https://aws.amazon.com/blogs/compute/detecting-and-stopping-recursive-loops-in-aws-lambda-functions/

它解释:

  1. 如何检测循环
  2. 在哪里检查循环
  3. 如何停止此循环检测
  4. 虚拟示例
© www.soinside.com 2019 - 2024. All rights reserved.