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 函数