You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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拆分分页任务,精准控制并发调用数:

  1. 编写初始化Lambda:调用API获取总页数或所有分页令牌;
  2. 在Step Functions中使用Map状态,将每个分页令牌作为单独任务,设置MaxConcurrency为120,确保同时运行的调用不超过120次;
  3. 每个Map任务调用专用Lambda,负责单页数据的获取;
  4. 最后通过状态汇总所有分页数据。

这种方案天然支持任务重试、失败处理,且能避免Lambda超时问题。

3. SQS中间层流量削峰

通过SQS将分页请求解耦,控制消费速率:

  1. 初始化Lambda:先调用API获取总页数/所有分页令牌,将每个分页请求封装为消息发送到SQS队列;
  2. 消费Lambda:配置为SQS队列的触发器,设置Lambda的预留并发数为120,同时将SQS的批量接收大小设为1;
  3. 消费Lambda每次从SQS获取一条消息,调用对应分页的API,完成后删除消息。

SQS的消息可见性超时可配合重试逻辑,确保不会因为API限流丢失任务。

4. Lambda并发控制(适用特定场景)

如果Lambda是被外部事件触发多次,且每次触发仅调用一次API,可直接通过Lambda的预留并发数控制总调用速率:将预留并发设为120,确保每秒最多有120个Lambda实例同时执行,从而将API调用速率控制在120次/秒以内。但此方案不适合单Lambda实例循环调用分页的场景。


内容的提问来源于stack exchange,提问作者chinahalffull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:50:24