You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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段有特殊限制,或者申请提高单来源的并发配额。
    • 优化重试逻辑:比如缩短最大重试等待时间,或者在重试前添加随机延迟,避免集中请求触发限流。

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_sigsfetch_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的并发任务数限制。

5. Lambda的并发调度限制

虽然你把内存拉满到10GB(对应CPU和网络带宽也会提升),但Lambda的异步调用并发可能受到账户级别的限制:

  • AWS Lambda默认的异步并发限制是1000(区域级),如果你的1000次调用刚好达到这个限制,会有部分请求被排队等待执行,导致总耗时增加。
  • 排查与解决
    • 查看CloudWatch的Lambda > Metrics > Async Invocations指标,看是否有Throttles(限流)的情况。
    • 如果确实达到并发限制,可以向AWS申请提高异步并发配额。

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

火山引擎 最新活动