如何在Node.js的AWS Lambda中实现120次/秒API调用限速
限制AWS Lambda对分页API的调用频率(每秒不超过120次)
针对Lambda循环调用分页API时的速率控制需求,以下是几种实用的解决方案:
1. Lambda内部实现速率控制
直接在Lambda代码中加入速率限制逻辑,是最轻量化的方案,适合单Lambda实例循环调用的场景。
令牌桶算法实现
可以借助第三方库或手动实现令牌桶逻辑,确保每秒调用次数不超过120次:
from ratelimiter import RateLimiter import requests import time # 配置速率:每秒最多120次调用 rate_limiter = RateLimiter(max_calls=120, period=1) def lambda_handler(event, context): next_page_token = None all_data = [] while True: # 每次调用API前先通过速率限制器 with rate_limiter: api_response = requests.get( "https://target-api.example.com/list", params={"page_token": next_page_token} ) # 处理API返回的限流错误(如429),配合重试逻辑 if api_response.status_code == 429: retry_after = int(api_response.headers.get("Retry-After", 1)) time.sleep(retry_after) continue api_response.raise_for_status() page_data = api_response.json() all_data.extend(page_data["items"]) next_page_token = page_data.get("next_page_token") if not next_page_token: break return {"total_data_count": len(all_data)}
手动计算调用间隔
如果不想依赖第三方库,可手动记录每次调用的时间戳,计算需要等待的间隔:
import time import requests def lambda_handler(event, context): next_page_token = None all_data = [] call_timestamps = [] max_calls_per_sec = 120 while True: # 清理1秒前的时间戳记录 now = time.time() call_timestamps = [t for t in call_timestamps if now - t < 1] # 如果已达每秒调用上限,等待至间隔满足 if len(call_timestamps) >= max_calls_per_sec: wait_time = 1 - (now - call_timestamps[0]) if wait_time > 0: time.sleep(wait_time) # 重新清理时间戳 now = time.time() call_timestamps = [t for t in call_timestamps if now - t < 1] # 调用API api_response = requests.get( "https://target-api.example.com/list", params={"page_token": next_page_token} ) api_response.raise_for_status() call_timestamps.append(time.time()) page_data = api_response.json() all_data.extend(page_data["items"]) next_page_token = page_data.get("next_page_token") if not next_page_token: break return {"total_data_count": len(all_data)}
2. 用AWS Step Functions编排调用
如果分页数量较大,Lambda单实例执行可能超时,可通过Step Functions拆分分页任务,精准控制并发调用数:
- 编写初始化Lambda:调用API获取总页数或所有分页令牌;
- 在Step Functions中使用
Map状态,将每个分页令牌作为单独任务,设置MaxConcurrency为120,确保同时运行的调用不超过120次; - 每个Map任务调用专用Lambda,负责单页数据的获取;
- 最后通过状态汇总所有分页数据。
这种方案天然支持任务重试、失败处理,且能避免Lambda超时问题。
3. SQS中间层流量削峰
通过SQS将分页请求解耦,控制消费速率:
- 初始化Lambda:先调用API获取总页数/所有分页令牌,将每个分页请求封装为消息发送到SQS队列;
- 消费Lambda:配置为SQS队列的触发器,设置Lambda的预留并发数为120,同时将SQS的批量接收大小设为1;
- 消费Lambda每次从SQS获取一条消息,调用对应分页的API,完成后删除消息。
SQS的消息可见性超时可配合重试逻辑,确保不会因为API限流丢失任务。
4. Lambda并发控制(适用特定场景)
如果Lambda是被外部事件触发多次,且每次触发仅调用一次API,可直接通过Lambda的预留并发数控制总调用速率:将预留并发设为120,确保每秒最多有120个Lambda实例同时执行,从而将API调用速率控制在120次/秒以内。但此方案不适合单Lambda实例循环调用分页的场景。
内容的提问来源于stack exchange,提问作者chinahalffull
相关产品推荐
相关产品推荐

