AWS Lambda执行1000次异步调用性能异常缓慢问题排查
听起来你遇到了一个挺让人头疼的问题——同样的1000次异步Solana RPC调用,本地/EC2跑起来只要5-10秒,到AWS Lambda就慢了6-12倍,就算拉满10GB内存也没改善。结合你的代码和Lambda的运行特性,我整理了几个可能的原因和排查方向:
可能的原因与排查建议
1. RPC节点对Lambda的限流/节流
你的代码里用了带退避的重试机制(@retry_with_backoff(11)),如果Lambda环境中发起的请求被RPC节点限流,就会频繁触发重试,直接拉长总耗时。
- 为什么本地没问题?:本地/EC2的IP相对固定,RPC节点可能对单IP的并发限制更宽松;而Lambda的请求来自动态的AWS IP池,大量并发请求可能被节点识别为批量访问,触发更严格的限流规则。
- 排查与解决:
- 查看Lambda日志里有没有重试相关的打印(比如
Retrying tx with empty result),确认是否频繁触发重试。 - 联系RPC节点提供商,确认是否对Lambda的IP段有特殊限制,或者申请提高单来源的并发配额。
- 优化重试逻辑:比如缩短最大重试等待时间,或者在重试前添加随机延迟,避免集中请求触发限流。
- 查看Lambda日志里有没有重试相关的打印(比如
2. 网络配置的瓶颈
Lambda的网络环境和本地/EC2差异很大,这很可能是核心原因:
- VPC限制:如果你的Lambda部署在VPC内,访问外部RPC节点需要通过NAT网关。NAT网关有并发连接数限制(默认每个NAT网关最多100000个并发连接),1000次异步调用同时发起可能会遇到连接排队;另外,VPC内的网络延迟也会比Lambda默认的公共网络高。
- 跨区域网络延迟:如果你的Lambda和Solana RPC节点不在同一个AWS区域,跨区域的网络延迟会累积。比如Lambda在
us-east-1,RPC节点在us-west-2,每次请求的延迟会从本地的几十ms变成几百ms,1000次下来总耗时就会暴涨。 - 排查与解决:
- 尝试把Lambda切换到公共网络(脱离VPC),测试是否提速。
- 确认RPC节点和Lambda在同一区域,或者选择距离更近的RPC节点。
- 如果必须用VPC,考虑增加NAT网关数量,或者启用NAT网关的连接复用。
3. 异步连接的复用问题
看你的代码,每次调用fetch_sigs和fetch_single_tx_details都新建一个AsyncClient:
async with AsyncClient(self.url) as client:
这意味着每次请求都会建立新的TCP连接,TCP三次握手的开销在高并发场景下会被放大。
- 为什么本地没问题?:本地的网络环境更稳定,连接复用的效率更高;而Lambda的运行时环境可能会因为实例生命周期短(比如短时间内销毁实例)导致连接无法复用,或者TCP连接的建立/关闭开销更大。
- 排查与解决:
- 把
AsyncClient改成全局单例,复用连接池。比如在Lambda handler外初始化一次客户端,后续所有请求复用这个客户端:# 在Lambda handler外初始化全局客户端 global_client = AsyncClient(your_rpc_url) async def fetch_sigs(self, marketplace, before=None, until=None, limit=5): sigs = (await global_client.get_signatures_for_address(SOL_MARKETPLACES[marketplace], before=before, until=until, limit=limit)).get("result", []) print(f'Fetched a total of {len(sigs)} sigs') return sigs - 检查
AsyncClient的连接池配置,确保它能处理1000次并发请求的连接需求。
- 把
4. Lambda的异步执行环境限制
Python在Lambda中的异步运行时可能存在一些容易被忽略的限制:
- 事件循环的初始化:如果你的Lambda handler是同步的,但内部调用异步函数,可能会因为重复创建事件循环导致性能损耗;或者事件循环的配置(比如线程数、并发数)不适合高并发场景。
- 日志输出的阻塞:代码里的
print语句是同步操作,Lambda的日志需要通过网络传输到CloudWatch,大量的print会阻塞异步任务的执行。 - 排查与解决:
- 确保Lambda handler是异步的(用
async def handler(event, context)),避免在同步函数中嵌套异步调用导致的循环开销。 - 把
print替换成Lambda的logging模块,并设置合适的日志级别,减少不必要的日志输出。 - 手动配置事件循环的参数,比如增加
asyncio的并发任务数限制。
- 确保Lambda handler是异步的(用
5. Lambda的并发调度限制
虽然你把内存拉满到10GB(对应CPU和网络带宽也会提升),但Lambda的异步调用并发可能受到账户级别的限制:
- AWS Lambda默认的异步并发限制是1000(区域级),如果你的1000次调用刚好达到这个限制,会有部分请求被排队等待执行,导致总耗时增加。
- 排查与解决:
- 查看CloudWatch的
Lambda > Metrics > Async Invocations指标,看是否有Throttles(限流)的情况。 - 如果确实达到并发限制,可以向AWS申请提高异步并发配额。
- 查看CloudWatch的
内容的提问来源于stack exchange,提问作者ilmoi




