我将我的 AWS Lambda 函数配置为处理 Amazon Simple Queue Service (Amazon SQS) 队列中的消息。我的一些有效的 Amazon SQS 消息在达到 maxReceiveCount 之前会被多次接收,最后进入我的死信队列。
简短描述
如果您的 Lambda 函数在读取 Amazon SQS 消息批量时受到限制、返回错误或不响应,则消息将返回您的队列。出现可见性超时后,您的 Lambda 函数会再次接收消息批处理。如果您的函数多次无法处理有效消息,则 Amazon SQS 会将消息发送到您的死信队列(如果您已配置死信队列)。
为了防止将有效消息置于死信队列中,您的函数代码必须是幂等且能够多次处理消息。有关更多信息,请参阅如何防止 Amazon SQS 消息多次调用我的 Lambda 函数?
解决方法
验证您的 Lambda 函数的代码是否为幂等
有关幂等性最佳实践和示例函数逻辑,请参阅如何使我的 Lambda 函数为幂等?
确认您的 Amazon SQS 队列的可见性超时时间至少比您的 Lambda 函数的超时设置长六倍
将源队列的可见性超时设置为至少比函数超时长六倍。如果函数在处理前一个批处理时受到限制,则额外的时间允许您的函数重试处理批处理。
有关更多信息,请参阅 Amazon SQS 开发人员指南中的设置可见性超时。
**请注意:**如果您的函数因为队列的可见性超时时间不够长而未收到消息,则消息将不会记录在您的 Amazon CloudWatch Logs中。
验证源队列的重新驱动策略中的 maxReceiveCount 属性是否设置为至少五个
将源队列重新驱动策略上的 maxReceiveCount 设置为至少五个。如果您的函数返回错误,或者因为它处于最大并发而无法调用,则处理可能会成功,但需要额外的尝试。maxReceiveCount 至少为五会让您的消息在发送到死信队列之前有更多的机会被处理。
要更新最大并发设置限制,请参阅为 Amazon SQS 事件源配置最大并发。
有关更多信息,请参阅《Amazon SQS 开发人员指南》中的死信队列如何工作?和避免消息处理不一致。
检查 Lambda 函数是否存在限制和预留并发
Lambda 函数有时会受到限制,以保护您的资源和下游应用程序。尽管 Lambda 会自动扩展以适应传入流量,但您的函数仍可能由于各种原因受到限制。
使用[ Lambda 控制台检查预留并发的设置](https://console.aws.amazon.com/lambda/)。如果未配置预留并发,则该函数使用非预留并发。当函数调用超过非预留并发时,就会出现限制。
**请注意:**如果您配置的函数的预留并发为零,则该函数会受到限制,因为它无法处理任何事件。请确保将该值增加到一个大于零的数字。
如果同一 AWS 区域中的其他函数使用并发限制,则可能会出现限制。受到限制的 Lambda 函数会将 SQS 消息发送到死信队列。
避免重新处理失败的批处理中的所有 SQS 消息
所有 SQS 消息在处理批处理时遇到错误的 Lambda 函数的死信队列中都可见,包括 Lambda 成功处理的消息。然后,Lambda 再次重试整批 SQS 消息。
为避免重新处理失败的批处理中的所有 SQS 消息,请使用 FunctionResponseTypes 列表中的 ReportBatchItem Failles 值配置事件源映射。这可以让您的函数返回部分成功消息并减少重试次数。有关更多信息,请参阅报告批处理项目故障。
识别并解决您的 Lambda 函数返回的任何错误
按照《如何解决 Lambda 函数故障?》中的说明进行操作只有当函数没有返回错误时,您的函数才会自动从队列中删除消息。
相关信息
如何请求提高我的 Lambda 函数的并发限制?
如何解决带有“超出速率”和 429 “TooManyRequestsException”错误的 Lambda 函数限制问题?