3. Serverless 应用场景:Web应用、数据处理、IoT后端、定时任务、API网关
Serverless 架构并非万能银弹,但在特定场景下能显著降低运维成本、提升弹性伸缩能力。本章聚焦五大典型落地场景,分析其架构模式、适用条件与常见陷阱。
3.1 场景总览与选型矩阵
不同业务场景对计算时长、冷启动敏感度、状态持久化、网络依赖的要求差异巨大。下表从关键维度对比五大场景,帮助你在项目初期快速判断是否适合 Serverless。
| 场景 | 典型执行时长 | 冷启动容忍度 | 状态需求 | 推荐触发器 | 主要限制 |
|---|---|---|---|---|---|
| Web 应用 / API | 100ms – 10s | 低(用户交互) | 无状态 + 外部 DB | API Gateway / ALB | 连接池复用、VPC 延迟 |
| 数据处理(ETL) | 1s – 15min | 高(批处理) | 无状态 + 对象存储 | S3 / Kafka / 定时 | 临时磁盘 512MB – 10GB |
| IoT 后端 | 100ms – 5s | 中(设备上报) | 无状态 + 时序 DB | MQTT / IoT Core | 并发设备数、消息去重 |
| 定时任务 / Cron | 30s – 15min | 高(后台执行) | 无状态 + 外部存储 | EventBridge / Scheduler | 最大超时 15min |
| API 网关 / BFF | 10ms – 1s | 极低(前端依赖) | 无状态 + 缓存 | HTTP / WebSocket | Payload 大小(通常 10MB) |
选型口诀: 有状态、长连接、GPU 密集、超长耗时 → 避开 Serverless;短任务、事件驱动、弹性波动大、运维人力少 → 优先 Serverless。
3.2 Web 应用与 API 后端
这是 Serverless 最成熟、用户量最大的场景。前端请求通过 API Gateway 或 ALB 触发函数,函数处理业务逻辑后返回 JSON/HTML。典型架构如下:
3.2.1 适用条件
- 请求量波动大: 如电商秒杀、活动 H5,平时低负载,峰值瞬间暴涨。
- 微服务拆分粒度细: 每个 API 对应一个函数,独立部署、独立扩缩。
- 前后端分离: 函数只输出 JSON,前端 SPA 或 SSR 独立托管。
3.2.2 常见陷阱
- 连接池耗尽: 函数实例数暴增时,数据库连接数被打满。解决方案:使用 RDS Proxy 或 PgBouncer。
- 冷启动延迟: 对首屏请求影响明显。解决方案:预留并发 + 依赖懒加载 + 使用 GraalVM Native Image。
- VPC 网络延迟: 函数在 VPC 内访问 RDS 时,每次调用增加 10–50ms 冷启动。解决方案:使用 VPC 代理或避免函数直接进 VPC。
案例: 某在线教育平台将课程列表 API 迁移至函数计算,平时 50 QPS,秒杀时峰值 5000 QPS。使用预留并发 200 实例 + RDS Proxy,冷启动从 800ms 降至 120ms,数据库连接数稳定在 300 以内。
3.3 数据处理(ETL / 实时流)
Serverless 天然适配“数据到达即处理”的事件驱动模型。无论是 S3 文件上传触发图片转码,还是 Kafka 消息触发日志清洗,函数都能按需执行,无需维护长期运行的集群。
3.3.1 典型场景
- 图片/视频处理: 上传原图到 S3 → 触发函数 → 生成缩略图/水印 → 存入目标桶。
- 日志清洗与聚合: 应用日志写入 Kafka → 函数消费并解析 → 写入 Elasticsearch 或 ClickHouse。
- 数据库变更捕获(CDC): DynamoDB Streams / Debezium → 函数同步到数仓或缓存。
3.3.2 性能调优要点
| 优化项 | 推荐做法 | 效果 |
|---|---|---|
| 内存配置 | CPU 性能随内存线性增长,IO 密集型选 1–2GB | 处理速度提升 2–5 倍 |
| 临时存储 | 挂载 /tmp 或 EFS,避免大文件在内存中处理 | 支持 GB 级文件 |
| 批处理 | Kafka/SQS 触发器设置 batchSize 100 | 减少函数调用次数 |
| 重试策略 | 设置死信队列(DLQ),失败消息自动隔离 | 数据不丢失 |
3.4 IoT 后端
物联网设备数量大、上报频率低、网络不稳定,非常适合 Serverless 的按需付费模型。函数处理设备消息后,写入时序数据库或触发告警。
3.4.1 架构要点
- 设备接入: 使用 IoT Core / MQTT Broker 接收设备消息,直接触发函数。
- 消息去重: 设备可能重复上报,函数内做幂等处理(基于设备 ID + 时间戳)。
- 下行指令: 函数通过 IoT Core 的 Shadow 或直接 MQTT 发布指令到设备。
- 时序存储: 推荐 TimescaleDB / InfluxDB / 时序 TSDB,按时间分区存储。
避坑提醒: 设备量超过 10 万时,函数并发数可能触发云厂商默认配额(通常 1000–3000)。提前申请提升并发上限,并设置函数级并发控制,避免单个设备类型打满全部配额。
3.5 定时任务 / Cron
使用云调度服务(EventBridge Scheduler / Cloud Scheduler)按 Cron 表达式触发函数,替代传统 crontab 或 Jenkins 定时器。适合数据备份、报表生成、健康检查、缓存预热等场景。
3.5.1 调度精度与限制
| 调度频率 | 最小间隔 | 最大超时 | 推荐场景 |
|---|---|---|---|
| 高频率 | 1 分钟 | 5 分钟 | 缓存刷新、健康检查 |
| 中频率 | 5 分钟 – 1 小时 | 15 分钟 | 报表聚合、日志轮转 |
| 低频率 | 每天 / 每周 | 15 分钟 | 全量备份、数据清理 |
3.5.2 幂等与重试
定时任务必须设计为幂等:即使同一时刻触发两次,结果也应一致。常见做法:
- 使用分布式锁(Redis / DynamoDB)确保同一任务只执行一次。
- 任务开始时记录执行批次 ID,结束时标记完成;下次执行前检查是否已处理。
- 失败时利用调度服务的重试机制(通常最多重试 3 次),并记录日志到死信队列。
3.6 API 网关 / BFF(Backend For Frontend)
API 网关在 Serverless 架构中承担路由、鉴权、限流、协议转换等职责,是函数的前置入口。BFF 模式则针对不同客户端(Web / iOS / Android)聚合数据,减少客户端请求次数。
3.6.1 网关核心功能
- 请求路由: 根据路径和方法分发到不同函数。
- 认证授权: JWT / OAuth2 / 校验,通过 Lambda Authorizer 实现。
- 限流与配额: 按用户/API/全局设置速率限制,防止恶意调用。
- 响应转换: 请求/响应体映射、CORS 头注入、压缩。
- WebSocket 管理: 维持长连接,函数推送消息到客户端。
3.6.2 BFF 实现示例
以下代码展示一个 BFF 函数,聚合用户信息和订单数据:
// BFF 函数:聚合用户首页数据
exports.handler = async (event) => {
const userId = event.requestContext.authorizer.claims.sub;
// 并行调用下游服务
const [userProfile, orders, notifications] = await Promise.all([
fetchUserProfile(userId),
fetchRecentOrders(userId),
fetchUnreadNotifications(userId),
]);
return {
statusCode: 200,
body: JSON.stringify({
user: userProfile,
orders: orders.slice(0, 5),
notifications: notifications.slice(0, 10),
}),
};
};
最佳实践: BFF 函数只做数据聚合和格式转换,不包含业务逻辑。业务逻辑下沉到领域函数,BFF 通过 HTTP 或 SDK 调用它们。这样 BFF 可以按客户端独立迭代,而领域函数保持复用。
3.7 场景选择决策树
当你面对一个新需求时,可以按以下步骤快速判断是否采用 Serverless:
- 任务时长 < 15 分钟? 是 → 继续;否 → 考虑容器或裸金属。
- 无状态或状态可外置? 是 → 继续;否 → 考虑有状态服务(如 K8s StatefulSet)。
- 请求量波动明显? 是 → 继续;否 → 传统部署成本可能更低。
- 团队运维能力有限? 是 → Serverless 降低运维负担;否 → 可自主选择。
- 依赖冷启动敏感? 低 → 直接使用;高 → 预留并发 + 优化依赖。