如何排查出现“Rate Exceeded”和 429 “TooManyRequestsException”错误时的 Lambda 函数限流问题?

上次更新时间:2020 年 2 月 20 日

我的 AWS Lambda 函数出现“Rate exceeded”和 429 “TooManyRequestsException”错误。为什么我的函数会被限流?

简短描述

限流旨在保护您的资源和下游应用程序。虽然 Lambda 会自动扩展以适应您的传入流量,但您的函数仍可能因多种原因被限流。请按照以下操作说明排查问题。

解决方法

验证受到限流的对象

有可能您看到的限流其实并非针对您的 Lambda 函数。函数调用期间可能会对 API 调用进行限流。

  1. 验证您是否在 Amazon CloudWatch Logs 中看到限流消息,但 Lambda Throttles 指标却没有对应的数据点。如果不存在 Lambda Throttles 指标,则说明 Lambda 函数代码中的 API 调用发生了限流。
  2. 检查函数代码以确定任何受到限流的 API 调用。如果特定的 API 调用受到限流,请首先使用代码中的指数回退来重试 API 调用。
  3. 如果您确定某个 API 调用需要更高的每秒事务处理数 (TPS) 配额,并且该配额也可调,则您可以请求提高服务配额

检查并发指标

  1. 检查 Amazon CloudWatch 中的 Lambda 指标。在您看到限流的 AWS 区域检查您的函数 ConcurrentExecutions 指标。
  2. 比较 ConcurrentExecutions 指标和 Throttles 指标,看时间戳是否相同。(查看 ConcurrentExecutions 指标的Maximum 统计数据,以及 Throttles 指标的 Sum 统计数据。) 检查 ConcurrentExecutions 的最大值是否接近您在该区域的账户级别并发配额,此外还需检查 Throttles 图中对应的数据点。
  3. 检查您是否超出了特定区域的初始突增并发配额。在 CloudWatch 控制台中,进入 Lambda 指标页面,将图的时间范围缩短至一分钟。如果您因突增扩展而受到限制,则您会看到 Throttles 突然出现峰值,并在图中对用出现 ConcurrentExecutions 阶梯模式。要解决突增并发限制问题,您可以配置预置并发
  4. 检查函数的 Duration 指标是否出现峰值。并发取决于函数的持续时间。如果代码执行时间过长,可能说明它没有足够的计算资源。请尝试增加函数的内存设置。然后使用 AWS X-RayCloudWatch Logs 来排查持续时间增加的原因。如果您的函数位于 Amazon Virtual Private Cloud (Amazon VPC) 中,请参阅如何为 VPC 中的 Lambda 函数提供互联网访问权限?以了解更多信息。
    注意:更改内存设置可能会影响有关执行时间的费用。
  5. 检查函数的 Error 指标是否有增加。错误增加可能会导致重试并造成调用数量的总体增加。(对于异步调用,Lambda 会额外重试两次失败的调用。) 调用增加可能会导致并发增加。使用 CloudWatch Logs 来识别和消除错误,并利用函数代码来处理异常。

配置预留并发

  1. 验证您是否在 Lambda 函数上配置了预留并发。使用 Lambda 控制台 或调用 GetFunction API 来检查设置。
    注意:如果某个函数配置为零预留并发,则该函数将被限流,因为它无法处理任何事件。请务必将该值增加到一个大于零的数字。
  2. 检查函数的 Maximum CloudWatch 统计数据,看它是否在任何时刻与 ConcurrentExecutions 指标的最大值匹配。
  3. 将函数的 预留并发增加到某个能使其避免限流的并发值。使用 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 控制台请求提高服务配额