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 可以按函数统计费用,及时发现异常