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。典型架构如下:

Web 应用 Serverless 架构 浏览器 / App API Gateway 函数计算 RDS / Redis 关键设计:函数内不保存本地状态,通过连接池代理(如 RDS Proxy)管理数据库连接。 冷启动优化:预留并发实例 + 依赖打包优化(减少 .zip 体积)。 ① HTTP 请求 ② 路由/鉴权/限流 ③ 业务逻辑执行 ④ 持久化/缓存

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 消息触发日志清洗,函数都能按需执行,无需维护长期运行的集群。

事件驱动数据处理流水线 S3 / Kafka / HTTP 事件触发器 数据处理函数 (转码/清洗/聚合) S3 / ES / 数仓 优势:数据分片自动并行,每个分片触发一个函数实例,无需手动管理并发。 限制:单个函数最大执行时长 15 分钟,超长任务需拆分为 DAG 或使用 Step Functions。

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:

  1. 任务时长 < 15 分钟? 是 → 继续;否 → 考虑容器或裸金属。
  2. 无状态或状态可外置? 是 → 继续;否 → 考虑有状态服务(如 K8s StatefulSet)。
  3. 请求量波动明显? 是 → 继续;否 → 传统部署成本可能更低。
  4. 团队运维能力有限? 是 → Serverless 降低运维负担;否 → 可自主选择。
  5. 依赖冷启动敏感? 低 → 直接使用;高 → 预留并发 + 优化依赖。