5月27日 10:45

Serverless 架构有什么缺点?冷启动、调试和成本问题怎么解?

用了两年 Serverless,踩了不少坑。冷启动延迟、调试困难、成本失控……这些问题在 PPT 里不会被提及,但上线后每一个都会咬你。下面按实际影响程度,逐一拆解 Serverless 架构的主要限制和应对策略。

冷启动:最让人头疼的延迟

函数一段时间没被调用后,运行环境会被回收。下次请求进来,平台得重新分配资源、加载运行时、初始化代码——这个过程就是冷启动。AWS Lambda 冷启动通常 200ms-5s,Java 等重运行时更慢,可能 10 秒以上。

应对方法:

  • 预留实例:花钱保活,适合对延迟敏感的核心接口
  • 轻量运行时:Go、Rust 比 Java/Node 冷启动快一个数量级
  • 定时心跳:每 5 分钟调一次函数防止回收(治标不治本,还浪费钱)
  • SnapStart:AWS 提供的快照恢复功能,Java 冷启动从 10 秒降到 200ms

执行时间和资源的天花板

AWS Lambda 最长执行 15 分钟,内存上限 10GB,/tmp 最多 10GB。视频转码、大数据批处理这类长任务直接超出限制。

解法不是硬塞进 Lambda,而是换架构:

  • 长任务用 AWS Fargate / Azure Container Apps,本质是 Serverless 容器,没有执行时间限制
  • 批处理用 AWS Step Functions 编排多个 Lambda,每个处理一部分
  • 大内存任务用 AWS Lambda 的 10GB 配置,但成本很高

状态管理的天然缺陷

Serverless 函数是无状态的——每次调用可能落在不同的实例上,实例间不能共享内存。这意味着:

  • 不能用全局变量缓存数据(下次请求可能不是同一个实例)
  • WebSocket 长连接需要借助 API Gateway + DynamoDB 维护
  • 用户会话必须存外部存储(Redis、DynamoDB)

这不是"限制"而是"设计约束"——接受无状态,把状态外置到专用服务,反而让架构更清晰。

调试和可观测性是硬伤

本地跑得好好的,部署到云端就出问题——环境差异、IAM 权限、网络配置都可能不一样。传统应用的断点调试在 Serverless 里基本不可行。

实际可用的调试手段:

  • 本地模拟:用 Serverless Framework 的 local invoke 或 AWS SAM 的 sam local,模拟云环境
  • 结构化日志:每个请求带 trace ID,用 CloudWatch/Loki 按请求链路追踪
  • X-Ray/Jaeger:分布式追踪,看清函数间的调用链和耗时
  • 预发布环境:和线上配置一致,上线前跑一遍集成测试

厂商锁定:被平台绑定的隐性成本

AWS Lambda 用了 API Gateway + DynamoDB + Step Functions,整套架构深度绑定 AWS。要迁到阿里云函数计算,代码、配置、基础设施全得重写。

降低锁定风险的策略:

  • 业务逻辑和基础设施解耦:核心代码不依赖云 SDK,通过适配层调用云服务
  • 用 Terraform/CDK 管理基础设施:换平台只改配置,不改业务代码
  • 优先选开放标准:容器镜像部署比原生函数更容易迁移
  • 现实一点:锁定是不可避免的,关键是评估迁移成本是否在可接受范围内

成本:看起来便宜,算起来不一定

Serverless 按调用量计费,低流量场景确实便宜。但高并发或被攻击时,费用可能远超预期——DDoS 攻击不只是安全风险,还是财务风险。

成本控制手段:

  • 设置并发上限和账单告警:AWS Lambda 支持账户级并发限制,防止失控
  • 对比预留实例和按需付费:稳定流量下预留实例更划算
  • 关注冷启动的间接成本:预留实例花钱,冷启动浪费请求时间,找到平衡点
  • 监控每次调用的成本:CloudWatch 可以按函数统计费用,及时发现异常
标签:Serverless