Lambda节流指标计数异常:为何节流数远超预期值?
为什么Lambda节流计数远超预期值?
核心原因:AWS SDK客户端自动重试节流请求
你使用的AWS SDK for JavaScript v3默认会对ConcurrentInvocationLimitExceeded(429节流错误)执行自动重试逻辑。当你一次性发送20个请求时:
- Lambda服务首先处理10个请求(达到并发软限制),剩余10个直接返回节流错误;
- SDK会按照默认的指数退避策略,自动重试这些被节流的请求;
- 由于你的Lambda函数每个执行需要2秒,重试请求发起时,前10个请求仍在运行,重试请求依然会被节流;
- 多次重试累加后,节流请求的总数就会远大于初始的10次,这就是你看到26次甚至更多节流的根本原因。
补充说明
- 节流请求无执行日志:被Lambda服务节流的请求不会进入函数执行环节,只有成功触发的请求才会生成CloudWatch日志。SDK的重试请求如果再次被节流,同样不会产生执行日志,所以你看不到重试相关的记录——这是客户端SDK发起的额外调用,而非Lambda服务端的重试。
- 并发指标统计偏差:
Total Concurrent Executions的统计可能存在时间粒度问题(比如你查看的是分钟级平均值而非实时峰值)。实际上第一次批量请求触发时,Lambda确实会达到10的并发上限,但后续重试请求分散在不同时间点,部分初始执行完成后重试请求可能成功,导致统计的峰值未被准确捕捉。
验证方案:禁用SDK重试
修改客户端配置,限制仅尝试1次调用(禁用自动重试),再测试即可得到预期的10次节流:
const { LambdaClient, InvokeCommand } = require("@aws-sdk/client-lambda"); // 配置客户端禁用自动重试 const client = new LambdaClient({ maxAttempts: 1, // 仅执行1次调用,不重试节流请求 }); const ITER = 20; const exec = async() => { const input = { FunctionName: "throttling-test", }; const command = new InvokeCommand(input); const tasks = []; for (let i = 0; i < ITER; i++) { tasks.push(client.send(command)); } const responses = await Promise.all(tasks); // 统计客户端收到的节流次数 const throttleCount = responses.filter(res => res.StatusCode === 429).length; console.log(`节流次数:${throttleCount}`); } exec()
内容的提问来源于stack exchange,提问作者KhanhND
相关产品推荐
相关产品推荐

