You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lambda与SQS触发器执行15次后停止触发问题排查

问题分析与解决

核心问题

你遇到的现象本质是原始SQS消息因Lambda未正确确认处理完成,被重复重试达10次后移入DLQ,而你观察到的“第16次发送的续跑消息”与原始消息的重试轨迹重叠,导致出现“消息飞行中但无法被拾取”的错觉。

原因拆解

  1. 消息确认机制缺失:
    当Lambda因超时/主动终止退出时,SQS不会自动删除当前处理的原始消息——只有当Lambda正常返回(无异常、无超时),SQS才会删除该批次的消息。你的逻辑是发送续跑消息后终止实例,导致原始消息未被确认删除,在可见性超时后重新回到队列,被Lambda反复拾取。
  2. 重试次数累积触发DLQ规则:
    SQS触发器默认配置了10次重试限制,当原始消息被重复拾取10次仍未被确认删除时,会被自动移入DLQ。你发送的第16次续跑消息,大概率是原始消息第10次重试时生成的,此时原始消息已进入DLQ,续跑消息则因之前的重试逻辑被标记为飞行状态,最终也因重复重试触发DLQ规则。

解决办法

1. 手动确认删除原始消息

在发送续跑消息前,调用SQS的delete_message接口删除当前处理的原始消息,避免其重复进入队列:

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):
    receipt_handle = None
    if ("Records" in event) and (len(event["Records"]) > 0):
        print("Trigger through SQS.")
        for record in event["Records"]:
            event = json.loads(record["body"])
            receipt_handle = record['receiptHandle']  # 保存消息的receipt handle
    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
        }
        # 先删除原始消息,再发送续跑消息
        if receipt_handle:
            sqsClient.delete_message(QueueUrl=SQS_URL, ReceiptHandle=receipt_handle)
        sqsClient.send_message(QueueUrl = SQS_URL, MessageBody=json.dumps(payload))
    else:
        # 任务完成时,也要删除原始消息
        if receipt_handle:
            sqsClient.delete_message(QueueUrl=SQS_URL, ReceiptHandle=receipt_handle)
        print("COMPLETED")
    
    print("end", datetime.utcnow())

2. 优化Lambda终止逻辑

避免强制终止Lambda实例(如调用exit()或抛出异常),确保发送续跑消息和删除原始消息的操作完成后,让Lambda正常返回。强制终止会导致SQS认为消息处理失败,触发不必要的重试。

3. 调整SQS触发器配置(可选)

如果业务需要保留原始消息的重试能力,可以在Lambda的SQS触发器配置中,调整重试尝试次数(默认10次),但这只是临时缓解,无法解决根本的重复消息问题。

复现场景验证

在你的复现代码中,Lambda超时20秒、SQS可见性超时30秒,若Lambda正常返回则消息会被自动删除;但如果Lambda因超时退出,原始消息会在30秒后回到队列,重复触发Lambda发送续跑消息,最终因10次重试进入DLQ。添加手动删除逻辑后,即可避免原始消息重复进入队列。

内容的提问来源于stack exchange,提问作者Ranjith kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 08:35:59