【问题标题】:Does a batch of messages from SQS become available for processing again, if the lambda timeouts?如果 lambda 超时,来自 SQS 的一批消息是否可以再次处理?
【发布时间】:2021-07-06 12:52:12
【问题描述】:

有一个 SQS 作为 lambda 的输入触发器。要从 SQS 获取的记录的批大小为 10。

在处理这 10 条记录时,如果 lambda 超时,是否所有这 10 条记录/消息都可以再次处理?还是会从 SQS 中删除已处理的那些?

我尝试在几个文档中查找此内容:link1link2。但是没找到。

如果这 10 条消息确实可供处理,那么我正在考虑实施的一个可能的解决方案是:处理完消息后继续删除它们。但是即使我删除了这些消息,它们会在 lambda 超时后变为可用吗?

【问题讨论】:

    标签: amazon-web-services aws-lambda amazon-sqs


    【解决方案1】:

    您链接的page on Visibility Timeouts 以这句话开头:

    当消费者接收并处理来自队列的消息时,该消息仍保留在队列中。

    您示例中的 Lambda 函数是来自 SQS 的消息的“消费者”。它接收并处理一批消息,但这些消息仍在队列中

    Using AWS Lambda with Amazon SQS上也有一个页面,简要提到了这一点:

    Lambda 分批读取消息并为每批调用一次您的函数。当您的函数成功处理一个批次时,Lambda 会从队列中删除其消息。

    在这里,Lambda 事件源提供部分“消费者”代码,并删除它知道已处理的消息。但它只有两种状态:你的 Lambda 函数成功,所以该批次应该被删除;或您的 Lambda 函数失败,因此不应删除该批次。

    为了让一些消息“成功”和一些“失败”,您需要告诉 SQS。在您处理每条消息时,没有单独的动词来“确认”它。再次引用可见性超时页面:

    因此,消费者收到并处理完消息后,必须从队列中删除。

    因此,如果您的 Lambda 函数想要将单个消息标记为已处理,则需要调用 the DeleteMessage API

    【讨论】:

      【解决方案2】:

      SQS 会在两种情况下将消息重新排队到您的 Lambda:

      1. 您的 Lambda 或 Lambda 服务返回/抛出错误。
      2. 在您的 Lambda 未完成的情况下已达到可见性超时。

      超时将被 Lambda 服务视为错误。因此,消息(及其记录)将再次发送到您的 Lambda。如果失败太频繁,则消息要么被丢弃,要么被发送到死信队列,具体取决于您的配置。

      如果您在完全处理之前从队列中删除了一条消息,它不会被重新发送,但您会冒数据丢失的风险。

      例如,如果您收到一条包含 10 条记录的消息,请立即从 SQS 中删除该消息,然后只处理 10 条记录中的 5 条,然后然后超时,将永远不会处理最后 5 条记录。

      所以我建议只删除已经完全处理的 SQS 消息。

      听起来很简单,但可能会变得棘手。例如:如果 10 条记录中有 9 条已成功处理,但有一条未成功处理,该怎么办。理论上,您应该返回一个错误,以便整个消息(及其 10 条记录)可以重新排队。但随后您将再次重新处理这 9 条成功记录。这可能会成为一个问题,具体取决于您的应用程序设计。 Idempotence 是你这里的朋友。

      【讨论】:

      • 要么我误解了消息和批次之间的关系,要么你有。我的理解是,有一些单独的消息(您称之为“记录”)以batch 的形式传递给 Lambda 函数。该批次不存在于队列中,它只是一种不那么频繁地调用 Lambda 函数的方式。如果批处理中的 10 条消息中有 9 条已处理,您可以删除这 9 条消息,一旦可见性超时到期,第 10 条消息将作为新批次的一部分重新发送。因此不存在数据丢失的风险。
      • @IMSoP 是的。但我以为您在谈论每条消息都有一个正文的用例,而正文又包含记录。例如,如果您有在创建新文件时通过 SQS 传递的 S3 事件,那么您的消息正文就是一个 S3 事件,它也可以包含多个记录。所以这些子记录可能很棘手。如果您只有一批 10 条消息,那么您是对的。删除其中 9 条然后返回错误只会将您没有从队列中明确删除的一条消息重新排队。
      猜你喜欢
      • 1970-01-01
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-29
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多