如何确保与 SQS 集成的 Lambda 调用的下游 API 在消息进入 DLQ 之前至少被调用 2 次?

Posted

技术标签:

【中文标题】如何确保与 SQS 集成的 Lambda 调用的下游 API 在消息进入 DLQ 之前至少被调用 2 次?【英文标题】:How can I ensure that a downstream API called by Lambda integrated with SQS is called at least 2 times before message going to DLQ? 【发布时间】:2020-08-07 16:54:04 【问题描述】:

我有 lambda 使用 SQS 事件作为输入。 SQS 队列也有一个 DLQ。 lambda 函数调用下游的 Restful API(调用此操作 DoPostToAPI()) 我需要保证 lambda 函数尝试调用 DoPostToAPI() at 至少 2 次​​strong>(在消息进入 DLQ 之前)

为了完成上述要求,我需要设置什么 Lambda Retries 和 SQS Redrive 策略配置?

我需要 100% 确定到达 DLQ 的消息仅会到达,因为它们已尝试发送到下游 API DoPostToAPI() 2 次,并且 由于任何其他原因消息不会到达 DLQ,如果可能的话。

对我来说,只有在尝试操作时消息才应该到达 DLQ 是有道理的,而不是出于其他原因(即我不希望消息到达 DLQ 纯粹是因为节流,因为 DoPostToAPI() 应该是在发送到 DLQ 之前先尝试)如果甚至没有尝试 lambda 函数操作,为什么我想要在 DLQ 上发送消息?换句话说,我需要保证在 item 移动到 DLQ 之前调用 lambda 操作。

我能得到一些帮助吗?由于 DoPostToAPI() api 调用失败,是否可以保证 DLQ 上的消息已经到达?还是(更不幸的是)消息到达 DLQ 的原因可能不是对下游 API 的调用失败?

从我目前在网上阅读的内容来看,lambda 可能在接收 SQS 消息并将消息移动到队列上不可见之后,可能遇到限制问题并重新尝试 lambda 调用。但是,如果它再次遇到 lambda 限制,它可能最终回到主队列,如果它达到其最大接收计数,则可以将消息放在 DLQ 上,而根本没有尝试 lambda。这是正确的吗?

为简单起见,让我们想象以下输入

SQSQueue1 SQSQueue1DLQ LambdaFunction1 --> ServiceClient1.DoPostToAPI()

lambda "maximum_retry_attempts" 和 SQS redrive_policy "maxReceiveCount" 之间的相互作用是什么

【问题讨论】:

Lambda 不知道“尝试”了什么。它只知道 Lambda 是如何完成/退出的。基于此,它将在 DLQ 中放入一条消息。如果您希望您的代码重试,那么您需要以这种方式编写代码。 您对此有 100% 的把握吗?我的意思是,重试可以通过队列重新驱动策略发生,不是吗?另外,如果“lambda”不知道重试,为什么它甚至在 lambda 本身上有 MaximumRetryAttempts 属性? 也许是语义。 Lambda 运行时环境不知道您的 Lambda 做了什么。 如果您的 Lambda 抛出未处理的异常或超时等,它将重试。您的代码必须告诉 Lambda 环境它失败了。我的评论与此有关。如果您的代码捕获远程 API 异常、记录它并正确返回,那么从 Lambda 运行时的角度来看,Lambda 成功。如果您的代码在您无法与下游服务交互时引发异常,那么您可以使用重试。我仍然认为您需要在内部编写 2 次重试代码。 “代码 2 内部重试”你到底是什么意思?此外,我仍然认为围绕 lambda“重试尝试”和 SQS maxRecieveCount 之间相互作用的细节尚未得到解决。如果您对自己的理解有信心,请随时提供答案,包括相互作用。我相信仍然有未解决的问题。对于我和更广泛的社区来说,获得一个简洁的答案会很棒。 再一次,我的目标是保证下游 API 至少被调用两次。这是一个真正需要强调的硬性要求。我感谢您和所有可以帮助确保我能够满足此要求的人。 【参考方案1】:

为了确保您的 lambda 在使用 SQS 时尝试重试,您只需设置 SQS 属性

maxReceiveCount

此值控制在消息进入死信队列之前对给定批次尝试多少 lambda 调用。

不幸的是,lambda 属性

maximum_retry_attempts

是否适用于使用 SQS 作为函数事件触发器的 lambda 函数。

【讨论】:

以上是关于如何确保与 SQS 集成的 Lambda 调用的下游 API 在消息进入 DLQ 之前至少被调用 2 次?的主要内容,如果未能解决你的问题,请参考以下文章

AWS Lambda 在向 SQS 发送消息之前完成

如何将 API Gateway 与 SQS 集成

消息发布到 SQS 时如何触发 lambda?

如何将Amazon SQS与Dynamodb集成

如何从外部 SQS 队列活动触发 AWS Lambda 函数

SQS DeleteMessage阻止并且不返回响应