如果 lambda 超时,来自 SQS 的一批消息是否可以再次处理?
Does a batch of messages from SQS become available for processing again, if the lambda timeouts?
有一个 SQS 充当 lambda 的输入触发器。从SQS中获取记录的批量大小为10。
在处理这10条记录时,如果lambda超时,这10条记录/消息是否都可以重新处理?还是已处理的将从 SQS 中删除?
我试图在几个文档中寻找这个:link1, link2。但是没找到。
如果这 10 条消息确实可以处理,那么我正在考虑实施的一个可能的解决方案是:在处理完消息后继续删除这些消息。但是,即使我删除了消息,一旦 lambda 超时,它们会变得可用吗?
在两种情况下,SQS 会重新排队发送给您的 Lambda 的消息:
- 您的 Lambda 或 Lambda 服务return/throw一个错误。
- 您的 Lambda 尚未完成,已达到可见性超时。
超时将被 Lambda 服务视为错误。因此,消息(及其记录)将再次发送到您的 Lambda。如果失败太频繁,消息将被丢弃或发送到死信队列,具体取决于您的配置。
如果您在完全处理一条消息之前将其从队列中删除,它不会被重新发送,但您运行 有数据丢失的风险。
例如,如果您收到一条包含 10 条记录的消息,立即从 SQS 中删除该消息,然后只处理 10 条记录中的 5 条,然后 然后 超时,最后 5 条记录将永远不会待处理。
所以我建议只删除已完全处理的 SQS 消息。
听起来很简单,但可能会变得棘手。例如:如果 10 条记录中有 9 条处理成功,但有一条未成功处理,该怎么办?理论上,您应该 return 一个错误,以便整个消息(及其 10 条记录)可以重新排队。但是你会再次重新处理这 9 条成功的记录。这可能会成为一个问题,具体取决于您的应用程序设计。 Idempotence 是你的朋友。
您链接到的 page on Visibility Timeouts 以这句话开头:
When a consumer receives and processes a message from a queue, the message remains in the queue.
您示例中的 Lambda 函数是来自 SQS 的消息的“消费者”。它接收并处理一批消息,但这些消息 仍在队列中 。
Using AWS Lambda with Amazon SQS上也有一个页面简单提到了这一点:
Lambda reads messages in batches and invokes your function once for each batch. When your function successfully processes a batch, Lambda deletes its messages from the queue.
此处,Lambda 事件源提供部分“消费者”代码,并删除它知道已处理的消息。但它只有两种状态:你的 Lambda 函数成功了,所以应该删除该批次;或者您的 Lambda 函数失败,因此不应删除该批次。
为了使某些消息“成功”而某些消息“失败”,您需要将此告知 SQS。在处理每条消息时,没有单独的动词来“确认”;再次引用可见性超时页面:
Thus, the consumer must delete the message from the queue after receiving and processing it.
因此,如果您的 Lambda 函数想要将个别消息标记为已处理,则需要调用 the DeleteMessage API。
有一个 SQS 充当 lambda 的输入触发器。从SQS中获取记录的批量大小为10。
在处理这10条记录时,如果lambda超时,这10条记录/消息是否都可以重新处理?还是已处理的将从 SQS 中删除?
我试图在几个文档中寻找这个:link1, link2。但是没找到。
如果这 10 条消息确实可以处理,那么我正在考虑实施的一个可能的解决方案是:在处理完消息后继续删除这些消息。但是,即使我删除了消息,一旦 lambda 超时,它们会变得可用吗?
在两种情况下,SQS 会重新排队发送给您的 Lambda 的消息:
- 您的 Lambda 或 Lambda 服务return/throw一个错误。
- 您的 Lambda 尚未完成,已达到可见性超时。
超时将被 Lambda 服务视为错误。因此,消息(及其记录)将再次发送到您的 Lambda。如果失败太频繁,消息将被丢弃或发送到死信队列,具体取决于您的配置。
如果您在完全处理一条消息之前将其从队列中删除,它不会被重新发送,但您运行 有数据丢失的风险。
例如,如果您收到一条包含 10 条记录的消息,立即从 SQS 中删除该消息,然后只处理 10 条记录中的 5 条,然后 然后 超时,最后 5 条记录将永远不会待处理。
所以我建议只删除已完全处理的 SQS 消息。
听起来很简单,但可能会变得棘手。例如:如果 10 条记录中有 9 条处理成功,但有一条未成功处理,该怎么办?理论上,您应该 return 一个错误,以便整个消息(及其 10 条记录)可以重新排队。但是你会再次重新处理这 9 条成功的记录。这可能会成为一个问题,具体取决于您的应用程序设计。 Idempotence 是你的朋友。
您链接到的 page on Visibility Timeouts 以这句话开头:
When a consumer receives and processes a message from a queue, the message remains in the queue.
您示例中的 Lambda 函数是来自 SQS 的消息的“消费者”。它接收并处理一批消息,但这些消息 仍在队列中 。
Using AWS Lambda with Amazon SQS上也有一个页面简单提到了这一点:
Lambda reads messages in batches and invokes your function once for each batch. When your function successfully processes a batch, Lambda deletes its messages from the queue.
此处,Lambda 事件源提供部分“消费者”代码,并删除它知道已处理的消息。但它只有两种状态:你的 Lambda 函数成功了,所以应该删除该批次;或者您的 Lambda 函数失败,因此不应删除该批次。
为了使某些消息“成功”而某些消息“失败”,您需要将此告知 SQS。在处理每条消息时,没有单独的动词来“确认”;再次引用可见性超时页面:
Thus, the consumer must delete the message from the queue after receiving and processing it.
因此,如果您的 Lambda 函数想要将个别消息标记为已处理,则需要调用 the DeleteMessage API。