2. 无服务器架构基础:无服务器计算模型(FaaS/BaaS)、事件驱动特性、冷启动与生命周期

在深入探讨 Golden Signals 的采集挑战之前,必须建立对无服务器架构核心模型的统一认知。本章将拆解 FaaS 与 BaaS 的职责边界、事件驱动的执行范式,以及冷启动这一影响所有可观测性指标的根本性因素。

2.1 无服务器计算模型:FaaS 与 BaaS

无服务器并非“没有服务器”,而是将服务器管理、容量规划和弹性伸缩完全抽象为平台责任。根据抽象层次的不同,无服务器计算模型主要分为两类:

维度 FaaS(函数即服务) BaaS(后端即服务)
核心单元 函数(Function)——一段无状态、事件驱动的代码 托管服务(数据库、认证、存储、消息队列)
计费粒度 调用次数 + 执行时长(通常精确到 1ms) 存储量、请求量、吞吐量(按资源使用)
伸缩单位 函数实例(通常 1 个并发 = 1 个实例) 服务级别自动伸缩(如 DynamoDB 的 WCU/RCU)
状态管理 无状态(状态需外移到 BaaS 或外部存储) 有状态(服务自身管理持久化)
典型产品 AWS Lambda、Azure Functions、Google Cloud Functions Amazon DynamoDB、Firebase Auth、Supabase
可观测性边界 函数执行上下文(内存、超时、冷启动) 服务端指标(延迟、错误率、限流)
关键认知: 在无服务器架构中,FaaS 是“计算胶水”,负责编排业务逻辑;BaaS 是“持久化基座”,负责存储与基础设施能力。Golden Signals 的采集必须同时覆盖这两层,且采集方式完全不同。

2.2 事件驱动特性:无服务器的执行引擎

无服务器架构本质上是事件驱动的。函数不会主动运行,而是由事件源触发。理解事件驱动模型是设计可观测性策略的前提。

  • 事件源(Event Source): 产生事件的实体,如 API Gateway HTTP 请求、S3 对象创建、Kinesis 数据流、定时器(CloudWatch Events)、SQS 消息等。
  • 触发器(Trigger): 事件源与函数之间的绑定关系。每个触发器定义了事件如何被映射为函数输入。
  • 执行上下文(Execution Context): 函数每次调用时被分配的资源沙箱,包含内存、CPU、环境变量和临时磁盘空间。
  • 异步调用 vs 同步调用: 异步调用(如 S3、SQS)将事件放入内部队列,平台负责重试;同步调用(如 API Gateway)直接等待函数返回。
无服务器事件驱动执行流程 事件源 API / S3 / SQS / Timer 触发器绑定 事件映射 & 权限 FaaS 执行环境 函数实例 (沙箱) 内存 / CPU / 临时磁盘 执行时长 (ms 计费) BaaS / 下游服务 数据库 / 存储 / 消息队列 可观测性关键点: 每个箭头代表一个可观测性边界:事件源延迟、触发器映射耗时、函数执行耗时、下游调用耗时。 Golden Signals 必须在这些边界上分别埋点,不能仅依赖函数内部日志。

2.3 冷启动与生命周期

冷启动(Cold Start)是无服务器架构中最具影响力的性能现象,也是 Golden Signals 采集的最大干扰项。它直接决定了延迟分布的长尾特征。

2.3.1 生命周期阶段

一个函数实例从创建到销毁经历以下阶段:

  1. 代码下载: 平台从存储(如 S3、容器镜像仓库)拉取函数代码包或 OCI 镜像。
  2. 沙箱初始化: 分配内存、配置环境变量、挂载临时文件系统(/tmp)。
  3. 运行时启动: 加载语言运行时(如 Node.js、Python、Java JVM)。
  4. 代码初始化: 执行全局/静态代码(如导入依赖、建立数据库连接池)。
  5. 函数处理: 等待并处理事件调用。
  6. 空闲保留: 执行完成后,实例保持存活一段时间(通常 5-15 分钟)以服务后续请求。
  7. 回收: 空闲超时后,平台回收实例。
冷启动 vs 热启动: 冷启动包含阶段 1-4,耗时通常在 100ms 到 10s+ 之间(取决于运行时和包大小)。热启动仅包含阶段 5,耗时通常在微秒到毫秒级。对于 Java/.NET 运行时,冷启动延迟可能比 Python/Node.js 高 5-10 倍。

2.3.2 冷启动对 Golden Signals 的影响

Golden Signal 冷启动影响 采集注意事项
延迟 冷启动请求延迟显著高于热启动,造成延迟分布呈现“双峰”或“长尾” 必须按冷/热启动维度拆分延迟百分位数(p50/p99/p999)
流量 突发流量导致大量并发冷启动,瞬时实例数飙升 监控并发实例数(Concurrent Executions)和冷启动率
错误 冷启动期间依赖初始化失败(如数据库连接超时)导致错误 区分初始化错误与业务逻辑错误;设置初始化超时告警
饱和度 冷启动消耗额外 CPU 和内存用于运行时加载,影响并发上限 跟踪“初始化持续时间”指标;预留并发(Reserved Concurrency)可缓解
冷启动与热启动时间线对比 冷启动时间线 代码下载 沙箱初始化 运行时启动 代码初始化 函数处理 空闲保留 回收 冷启动总耗时 (100ms ~ 10s+) 热启动时间线 函数处理(直接执行) 空闲保留 回收 热启动总耗时 (μs ~ ms) 冷启动延迟差异可达 1000 倍以上。采集延迟指标时必须标记请求是否为冷启动,否则 p99 将严重失真。

2.4 生命周期对可观测性采集的启示

  • 初始化代码必须埋点: 在全局/静态初始化块中添加计时和日志,否则冷启动延迟会被计入第一个请求的“函数处理”阶段,导致误判业务逻辑性能。
  • 预留并发策略: 通过设置预留并发(Reserved Concurrency)保持一定数量的热实例,可显著降低冷启动率,但会增加成本。
  • Provisioned Concurrency(预置并发): AWS Lambda 等平台支持预置并发,在函数更新后立即初始化指定数量的实例,消除冷启动。但需要额外付费。
  • 异步初始化(Lambda 扩展): 利用 Lambda Runtime API 的初始化阶段钩子,在扩展层完成预热,减少对函数代码的侵入。
最佳实践: 在函数日志中输出 INIT_START 和 INIT_END 时间戳,结合平台提供的 InitDuration 指标(AWS Lambda 内置),构建冷启动延迟的独立监控面板。这是 Golden Signals 中“延迟”信号的最重要子维度。