如何排查出现“Rate Exceeded”和 429 “TooManyRequestsException”错误时的 Lambda 函数限流问题?
上次更新时间:2020 年 2 月 20 日
我的 AWS Lambda 函数出现“Rate exceeded”和 429 “TooManyRequestsException”错误。为什么我的函数会被限流?
简短描述
限流旨在保护您的资源和下游应用程序。虽然 Lambda 会自动扩展以适应您的传入流量,但您的函数仍可能因多种原因被限流。请按照以下操作说明排查问题。
解决方法
验证受到限流的对象
有可能您看到的限流其实并非针对您的 Lambda 函数。函数调用期间可能会对 API 调用进行限流。
- 验证您是否在 Amazon CloudWatch Logs 中看到限流消息,但 Lambda Throttles 指标却没有对应的数据点。如果不存在 Lambda Throttles 指标,则说明 Lambda 函数代码中的 API 调用发生了限流。
- 检查函数代码以确定任何受到限流的 API 调用。如果特定的 API 调用受到限流,请首先使用代码中的指数回退来重试 API 调用。
- 如果您确定某个 API 调用需要更高的每秒事务处理数 (TPS) 配额,并且该配额也可调,则您可以请求提高服务配额。
检查并发指标
- 检查 Amazon CloudWatch 中的 Lambda 指标。在您看到限流的 AWS 区域检查您的函数 ConcurrentExecutions 指标。
- 比较 ConcurrentExecutions 指标和 Throttles 指标,看时间戳是否相同。(查看 ConcurrentExecutions 指标的Maximum 统计数据,以及 Throttles 指标的 Sum 统计数据。) 检查 ConcurrentExecutions 的最大值是否接近您在该区域的账户级别并发配额,此外还需检查 Throttles 图中对应的数据点。
- 检查您是否超出了特定区域的初始突增并发配额。在 CloudWatch 控制台中,进入 Lambda 指标页面,将图的时间范围缩短至一分钟。如果您因突增扩展而受到限制,则您会看到 Throttles 突然出现峰值,并在图中对用出现 ConcurrentExecutions 阶梯模式。要解决突增并发限制问题,您可以配置预置并发。
- 检查函数的 Duration 指标是否出现峰值。并发取决于函数的持续时间。如果代码执行时间过长,可能说明它没有足够的计算资源。请尝试增加函数的内存设置。然后使用 AWS X-Ray 和 CloudWatch Logs 来排查持续时间增加的原因。如果您的函数位于 Amazon Virtual Private Cloud (Amazon VPC) 中,请参阅如何为 VPC 中的 Lambda 函数提供互联网访问权限?以了解更多信息。
注意:更改内存设置可能会影响有关执行时间的费用。 - 检查函数的 Error 指标是否有增加。错误增加可能会导致重试并造成调用数量的总体增加。(对于异步调用,Lambda 会额外重试两次失败的调用。) 调用增加可能会导致并发增加。使用 CloudWatch Logs 来识别和消除错误,并利用函数代码来处理异常。
配置预留并发
- 验证您是否在 Lambda 函数上配置了预留并发。使用 Lambda 控制台 或调用 GetFunction API 来检查设置。
注意:如果某个函数配置为零预留并发,则该函数将被限流,因为它无法处理任何事件。请务必将该值增加到一个大于零的数字。 - 检查函数的 Maximum CloudWatch 统计数据,看它是否在任何时刻与 ConcurrentExecutions 指标的最大值匹配。
- 将函数的 预留并发增加到某个能使其避免限流的并发值。使用 Lambda 控制台 或调用 PutFunctionConcurrency API 来更改设置。
在应用程序中使用指数回退
作为一项最佳实践,请在调用 Lambda 函数的应用程序中使用指数回退来重试受到限流的请求。
使用死信队列
如果您使用的是 Amazon Simple Storage Service (Amazon S3) 和 Amazon CloudWatch Events 等异步事件源,则为您的函数配置死信队列 (DLQ) 来捕获任何因持续限流而被丢弃的事件。这可以在您看到严重限流时保护您的数据。
注意:对于 Amazon Simple Queue Service (Amazon SQS) 事件源,您必须在 Amazon SQS 队列上配置 DLQ。
请求提高服务配额
如果您确定您的工作负载需要更高的服务配额以确保并发执行,您可以在 Service Quotas 控制台请求提高服务配额。