AWS - SQS 批量大小和 Lambda 方法

Posted

技术标签:

【中文标题】AWS - SQS 批量大小和 Lambda 方法【英文标题】:AWS - SQS Batch Size and Lambda approach 【发布时间】:2019-07-01 14:37:59 【问题描述】:

如果我理解正确,Lambda 上的批量大小设置决定了从 SQS 一次扫描中接收多少消息。因此这个 JSON(取自测试 Lambda SQS);


  "Records": [
    
      "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
      "receiptHandle": "MessageReceiptHandle",
      "body": "FAIL",
      "attributes": 
        "ApproximateReceiveCount": "1",
        "SentTimestamp": "1523232000000",
        "SenderId": "123456789012",
        "ApproximateFirstReceiveTimestamp": "1523232000001"
      ,
      "messageAttributes": 
      ,
      "md5OfBody": "7b270e59b47ff90a553787216d55d91d",
      "eventSource": "aws:sqs",
      "eventSourceARN": "arn:aws:sqs:eu-west-1:123456789012:MyQueue",
      "awsRegion": "eu-west-1"
    
  ]

有 Records 数组。如果我将批量大小设置为 5,那么如果 SQS 中有 5 条消息,它们将包含在数组中。如果有 10 条消息,则 Lambda 将被调用两次,每条 Record 中有 5 条消息。

我现在有点困惑,不知道该采取什么方法。我的 Lambda 相当简单。它将是对外部服务的 Axios POST 请求。如果它出错,我会抛出一个错误。我什至可以使用 axios-retry,让重试变得相当容易。

我应该在我的情况下使用批处理吗?天真地看着,我只需要1对1。换句话说,消息到达。拉姆达接受它。如果出错,稍后会自动重试。

相反,我必须遍历所有消息并尝试 Axios 请求。如果五条消息中的第三条失败了怎么办,在这种情况下我会抛出一个错误并且 Lambda 会停止。消息四和五会发生什么?他们是否被重新发送到 SQS,然后再次被拾起以进行另一次执行?

【问题讨论】:

【参考方案1】:

我只需要1对1。换句话说,消息到达。拉姆达需要 它。如果出错,稍后会自动重试。

我认为在上述情况下您不需要批处理。

如果五条消息中的第三条失败了怎么办,在这种情况下我会抛出一个 错误并且 Lambda 停止。消息四和五会发生什么? 他们是否被重新发送到 SQS,然后再次被拾起以进行另一次执行?

如果您的 Lambda 错误,消息将不会从队列中删除,基于 SQS visibility timeout 和 redrive policy 配置。 SQS 会根据配置再次触发 Lambda。如果您已配置 DLQ,则在达到 maxReceiveCount 后,失败的消息将被添加到 DLQ 并从主队列中删除。

【讨论】:

在 lambda 中,我会在处理完每个队列后从 sqs 队列中进行编程删除。这应该可以防止它重新发送成功的那些。然后,如果我有任何错误,我会抛出一个异常来指示那些失败(没有被删除)的人重新排队 当您在 10 个批次中收到一个“坏”消息并且它位于第 5 位并且我的 Lambda 引发异常时会发生什么。如果我配置了 DLQ,那么在达到 maxReceiveCount 之后,是否只有消息 5 放在 DLQ 上?还是将消息 6、7、8、9 和 10 也放在 DLQ 上?这将假设消息 6-10 涉及在每次调用期间包含消息 5 的那批消息。 @Gillfish SQS 不知道这 10 个批次中的哪一个失败,因此它别无选择,只能最终将所有 10 个发送到 DLQ。如果您想要更多粒度,但仍使用批处理,那么您的 Lambda 函数可以从 SQS 队列中显式删除每条成功的消息,只在 SQS 队列中留下未处理和失败的消息。例如,使用npmjs.com/package/@middy/sqs-partial-batch-failure

以上是关于AWS - SQS 批量大小和 Lambda 方法的主要内容,如果未能解决你的问题,请参考以下文章

配置Java AWS Lambda使用的Objectmapper

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

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

使用 AWS 无服务器和 NodeJS 在接收器 lambda 处未接收到来自 SQS 的所有消息

从 AWS Lambda 读取 SQS 队列

从AWS Lambda向SQS队列发送数据时重置连接