我正在设计一个系统解决方案,其中 SQS 队列触发 Lambda,队列接收大量消息进行逻辑分组,例如
execId
。 lambda 批量从队列中读取消息,对于相同的 execId
,它会创建一条新消息,添加从队列接收到的消息的 firstMsgTimestamp
和 lastMsgTimestamp
,并将其放回到同一个队列中。对于带有 firstMsgTimestamp
和 lastMsgTimestamp
的消息,它会检查 lastMsgTimestamp
是否超过 2 分钟前,如果是,它不会将消息发布回队列,而是处理下游事件(例如进行 API 调用) ,或调用另一个 lambda 等) - 这可确保放回队列的消息不会在 2 分钟后递归运行。该架构如下所示。
但是,AWS 报告此 lambda 正在递归运行,并在 AWS Health Dashboard 中发送以下警报
AWS Lambda 检测到您的 AWS 账户中的一个或多个 Lambda 函数正在与其他 AWS 资源进行递归循环调用。
经过研究,我发现 SQS 使用 XRay 跟踪标头来识别递归循环,如 AWS 帖子中所述此处。
我为每条消息生成了唯一的 AWS 跟踪标头,并将消息发送到 SQS,其中每条消息的内容都是唯一的,使用以下代码:
{
Id: crypto.randomUUID(),
MessageBody: JSON.stringify(message),
MessageSystemAttributes: {
AWSTraceHeader: {
DataType: 'String',
StringValue: generateTraceHeader(),
},
},
}
我添加了日志来验证
generateTraceHeader()
函数生成的标头是否与通过记录整个消息记录进入消息的标头相同,并且它们都是相同的,因此我确信该消息具有 AWS 跟踪我生成的标头。此外,我生成的 AWS 跟踪标头没有 AWS 本身注入到标头中的 Lineage
标头信息,这也确认了消息具有我生成的跟踪标头。
但是,AWS 仍然报告 lambda 的递归循环并删除 lambda 调用(下面附有屏幕截图):
我还尝试禁用 SQS 或 lambda 的跟踪,但 Node SDK 目前似乎不支持禁用跟踪,因为存在一个开放的 GitHub 问题here。
有谁知道如何阻止 AWS 将此检测为递归循环,而无需联系 AWS 并要求他们关闭 Lambda 的递归循环预防?
我也有类似的问题。我通过以下步骤修复了它:
"aws-sdk": "2.1017.0"
。我使用的是node18,因此默认情况下aws-sds v2不包含在AWS节点映像中,因此我必须显式安装它。请参阅AWS 文档。 package.json 中的一些依赖项也可能依赖于 aws-sdk,因此您需要仔细检查您运行的版本。aws-xray-sdk-core
。就我而言,我不得不停止将它与 SQS 客户端一起使用。