【Serverless】Serverless 详解
注:文中“Serverless”泛指“把服务器管理从开发者职责中抽象出去”的计算模型(FaaS / BaaS / Serverless containers 等)。(Amazon Web Services, Inc.)
一、Executive summary(要点回顾)
- Serverless = 抽象掉服务器的运维细节,让开发者以事件/函数/服务(高层构件)为单位交付业务代码;底层仍然有服务器,只是由平台/云厂商管理并按需调度计费。(Amazon Web Services, Inc.)
- 核心模型:FaaS(Function-as-a-Service)、BaaS(Backend-as-a-Service)、以及“serverless containers / services” 等。
- 关键设计目标:极简的运维、自动按需弹性(瞬时伸缩)、按使用付费、事件驱动和高开发效率。
- 代价与挑战:冷启动、无状态模型对架构影响、调试/本地化复杂、潜在的供应商锁定。研究与实践已系统化(学术与工业文献对利弊做了深入分析)。(ACM通讯)
二、为什么要 Serverless?动机与价值
2.1 运维成本与关注点转移
传统应用需关心 VM/OS/patch/autoscaling/容量计划;Serverless 把这些交给平台(云厂商或 PaaS)。目标是把团队注意力从“如何管理运行环境”转到“如何快速实现业务逻辑”。
2.2 更细粒度的弹性与成本模型
Serverless 支持基于事件短暂弹性实例(冷/热实例),通常按运行时间或请求计费,降低闲置成本,适合突发性、变化多样的负载。
2.3 快速交付与事件驱动架构(EDA)
Serverless 推动事件驱动系统设计:事件源(HTTP、消息、存储变更、定时器)直接触发函数,简化异步/可组合架构。
三、Serverless 的分类与技术栈
3.1 主要范式
- FaaS(Function-as-a-Service):最典型的 serverless 模式,开发者上传函数(handler),由平台在事件触发时执行(AWS Lambda、GCP Cloud Functions、Azure Functions)。AWS 在 2014 年推出 Lambda,引爆了该范式的普及。(Amazon Web Services, Inc.)
- BaaS(Backend-as-a-Service):把“后端服务”抽象为 API(Auth、DB、存储、消息、push 等),开发者直接调用托管服务(例如 Firebase、Auth0、Managed DB)。
- Serverless containers / service platforms:把容器作为“serverless 单位”,例如 Cloud Run、Knative、OpenFaaS 的某些模式(保持容器镜像作为部署单元但支持自动缩到零与快速弹性)。Knative 是 Kubernetes 上的 serverless 层代表方案。(InfoQ)
3.2 典型平台与生态(示例)
- 公有云:AWS Lambda, Google Cloud Functions, Azure Functions, Cloud Run(serverless containers)。(Amazon Web Services, Inc.)
- 开源 / 可部署:Knative(K8s 上的 serverless),OpenFaaS, Fn Project, Apache OpenWhisk 等。Knative 将 serverless 抽象带到 Kubernetes 上,促进可移植性。(Knative)
四、Serverless 的架构要素(高层图 + 说明)
关键组件说明:
- Event Sources:HTTP/API、消息队列、对象存储变更、定时器、第三方 Webhook。
- API Gateway / Router:统一入口,做身份校验、路由、请求聚合、流量限制。
- Function Control Plane:负责函数部署、版本、权限管理、触发器配置、指标采集。
- Function Execution Pool / Data Plane:承载实际执行的环境(容器或轻量虚拟机),实现隔离、冷/热实例管理、并发控制。
- State / Storage:持久层(managed DB、object store、KV、cache),用于函数持久化或跨调用通信。
- Observability / Security / CI:日志、tracing、metrics、安全策略与自动化交付管道。
五、函数执行模型与实现细节
5.1 执行环境:容器 vs microVM vs language runtime
- 许多云厂商在执行层使用轻量虚拟化(microVMs,例:Firecracker) 或容器来实现多租户隔离与快速启动;Firecracker 在 Lambda 的实现中被用于实现更强的隔离同时保持启动速度。平台差异会影响冷启动与资源隔离策略。(维基百科)
5.2 冷启动(Cold start)与保活(Warm)策略
-
冷启动:当没有 warm 实例可用时,平台需分配新的容器/VM、拉取镜像、初始化 runtime,这会显著增加延迟(对实时性敏感的场景是关键痛点)。解决手段:
- 预热(保留 warm instances)
- 轻量运行时(AOT 编译、smaller runtimes)
- 快照/恢复(例如 Lambda 的 SnapStart-like 技术)
- 调整 function 的内存(内存大 = 更高 CPU = 更短冷启动)
-
平台与语言对冷启动影响很大:Go、Rust 一般冷启动快;Java/.NET 有额外 runtime 初始化开销。(维基百科)
5.3 并发与吞吐
- 平台通常支持水平并发扩缩:当并发请求增加,平台会启动更多实例(按需伸缩)或并发路由到已有实例(如果实例支持多并发)。设计时要理解 provider 的并发语义(例如 Lambda 的预配置并发、最大并发限制、容器内多线程并发能力)。
5.4 无状态首选、外部化状态
- 函数应尽量设计为无状态:任何需要保留跨调用的状态都应放在持久化层(DB、KV、object store、durable queue)或使用专门的 stateful serverless 建设(见后述)。
六、Serverless 的编程模型与设计原则
6.1 事件驱动与短时任务
- 函数是“短小单一责任”的程序单元,通常处理单个事件并很快返回(best-effort latency)。推荐:每个函数实现单一业务职责、幂等处理、可重试。
6.2 幂等性与重试策略
- 由于平台/网络可能导致重复执行或重试,函数必须设计成幂等(去重、唯一请求 ID、事务边界)。
6.3 时间与资源约束
- 函数有执行超时(provider 限制),要将长时任务拆解为异步工作流或使用 step functions/worker queue。
6.4 Composition(函数组合)与 Orchestration
-
两类方法:
- Orchestration(外部工作流):使用状态机(AWS Step Functions、Google Workflows)控制函数调用、分支、重试、补偿逻辑。优势:更容易观察与错误恢复。
- Choreography(事件链式):函数产生事件并发布到消息总线;下游函数订阅事件并处理。优势:解耦、可扩展,但更难调试和保证一致性。
七、常见架构模式(典型场景与示例)
7.1 API Backend(HTTP → Function → DB)
- API Gateway 接收请求 → 验证/限流 → 调用函数 → 函数读写 DB → 返回 Response。适合快速构建 micro-backends 与小规模 REST 服务。
7.2 Event-driven ETL / Pipeline
- 数据流(S3 events / kafka / pubsub)触发函数做 extract/transform/load;配合 orchestrator 实现复杂步骤。常用于日志处理、图像处理、数据归档。
7.3 Fan-out / Fan-in (Parallel processing)
- 发布大量工作到并行函数执行,最后用聚合函数或 reduce 阶段合并结果(注意并发限额与半聚合策略)。
7.4 Scheduled tasks / Cron
- Scheduled triggers(Cloud Scheduler / EventBridge)触发定期函数做批处理/维护任务。
7.5 Orchestrated workflows(Saga / Step Functions)
- 适合跨函数事务逻辑:有专门工作流引擎管理状态、超时、补偿步骤(例如 Step Functions),减少函数内复杂控制。
八、Stateful Serverless(难点与进展)
传统 serverless 强调无状态,但现代需求推动有状态函数或durable serverless 技术的发展:
8.1 Durable Functions / Stateful Workflows
- 平台/框架(如 Durable Functions, Azure Durable, AWS Step Functions)提供机制在 control plane 中保存状态、调度下一步任务、并能在失败后恢复流程。
8.2 External state services (best practice)
- 把状态放在专门可扩展的服务:DynamoDB、Redis、Cloudflare Workers KV、FaunaDB、CockroachDB 等。设计要考虑一致性、延迟与成本。
8.3 Emerging: stateful function runtimes
- 研究与产品探索将状态管理内嵌到 function runtimes(workflows / stateful functions / Function-as-a-Service with built-in state),但复杂性与运维代价较高。学术界和厂商都在推动“stateful serverless”路线的解决方案。(ACM通讯)
九、可观测性、调试与本地开发
9.1 观测(Logging / Tracing / Metrics)
-
必备:
- 集中化日志(per invocation)(有 request-id / trace-id)
- 分布式 tracing(跨函数调用链路)
- 高粒度 metrics(invocation count, duration, errors, cold start count)
-
平台通常提供 logs + metrics 集成(CloudWatch, Stackdriver 等),但要设计良好 tracing(OpenTelemetry)以支持根因分析。
9.2 调试与本地化
-
本地调试困难:函数在云平台的运行环境与本地不同。常用手段:
- 本地化模拟器(SAM CLI, Functions Framework)
- 将核心业务逻辑抽离成可在普通进程运行的模块,函数仅作调用包装
- 使用入云端的测试/Stage 环境进行整合 E2E 测试
9.3 测试
- 单元测试(纯逻辑)
- 集成测试(与 DB、消息总线)
- 合规性测试(权限、timeout、cold start regression)
十、安全与多租户隔离
10.1 最小权限原则
- 每个函数应使用最小必要权限(细粒度 IAM / role);避免过度权限导致横向攻击扩散。
10.2 Secrets 管理
- 使用专门的 Secrets 管理(KMS / Secret Manager),不要把敏感数据写进函数代码或环境明文。
10.3 多租户、资源隔离
- 多租户平台需在执行层使用 strong isolation(microVM、gVisor)、网络策略、resource cgroups 限制。Firecracker microVMs 是其中常见实践(Lambda 的一部分实现使用它)。(维基百科)
十一、成本模型与优化策略
11.1 成本特点
- 计费一般基于执行时间 × 分配资源(内存/CPU) + 请求次数 + 外部服务调用(DB/Network)。按使用付费带来节省但也会因高调用次数或长期运行的 warm containers 产生成本。
11.2 成本陷阱
- 高并发频繁触发大量短时函数(大量启动/初始化)可能比长时容器更贵。
- 大量小函数的冷启动成本、DynamoDB 请求/存储费用、或跨区域网络费用都可能隐藏真实成本。
11.3 优化方法
- 合并小函数减少调用次数(在不牺牲可维护性的前提下)
- 调整内存/CPU 配置(通过微基准测试找到成本/延迟平衡点)
- 使用预留并发或 provisioned concurrency(部分平台)以减少冷启动并提高稳定性(但这会引入固定费用)
十二、可移植性与供应商锁定
12.1 锁定因素
- 专用触发器、IAM 语义、运行环境(例如 Lambda-specific lifecycle features)、平台原生服务(DynamoDB、S3)会导致迁移复杂度。
- Workflows/orchestration(Step Functions)与 BaaS 服务也会造成锁定。
12.2 减少锁定的策略
- 把业务逻辑写成与云无关的模块,函数作为适配层(adapter pattern)。
- 使用开源/跨云 serverless 平台(Knative、OpenFaaS、Fn Project)或利用容器化 serverless(Cloud Run / KEDA / Knative)以便在 Kubernetes 上运行。Knative 是 K8s 上的 serverless 层,支持容器镜像与自动缩到零等特性,有助于跨云部署。(Knative)
十三、Serverless on Kubernetes(Knative & friends)
- Knative:在 Kubernetes 上构建 serverless 的组件集(Serving, Eventing, Build/Buildpacks),把 serverless 的“scale-to-zero、autoscale、eventing”带到 K8s 上,使组织既能享受 serverless 开发模型,又能保留平台控制与可移植性。Knative 于 2018 年发布,已成为 K8s 上重要的 serverless 方案之一。(InfoQ)
十四、实践建议(Checklist / Patterns / Do & Don’t)
Do(推荐实践)
- 设计函数为短小、幂等、无状态,把状态放到可靠数据层。
- 使用 tracing + structured logs + metrics 做端到端观测。
- 把通用库/重逻辑抽象为容器可复用组件或 shared library,函数仅作 glue。
- 对关键路径使用预留并发/Provisioned concurrency(或在容器 serverless 上使用预热策略)以保证低延迟。
- 用 workflow/orchestration 管理复杂事务或长时任务(避免函数内复杂控制流)。
Don’t(常见反模式)
- 把长时间运行任务塞进单一函数(会受平台超时限制)。
- 忽视幂等性(会导致重复写入、资源泄漏)。
- 把大量敏感信息硬编码在函数或环境变量中(使用 Secrets manager)。
- 单纯以“省钱”作为迁移 serverless 的唯一理由(需要综合评估运维成本/复杂度/性能要求)。
十五、若干 Mermaid 图(运维/调用/工作流示意)
高层调用链(简化)
函数启动 / 冷启动示意
Event-driven pipeline with orchestration
十六、研究与未来方向(趋势)
- Edge Serverless:将函数下沉到边缘节点(Cloudflare Workers、Fastly),对低延迟应用(IoT、实时推理)有吸引力。
- Stateful serverless:把状态管理纳入平台(like Durable Functions / stateful FaaS),以简化复杂业务的开发。
- Function composition as a first-class primitive:更强的 declarative composition、可观测化与事务语义支持。
- Open standards & portability:Knative、CloudEvents(事件规范)等推动跨云互操作性与更少的 lock-in。(Knative)
十七、结论(工程师应该怎样开始 / 评估)
- 先试小场景:把非关键、低延迟要求不高、事件驱动的任务迁移到 serverless(图像处理、webhooks、cron job)。
- 明确 SLA:如果对延迟或长期运行有硬性要求,慎用纯 FaaS;考虑 serverless containers 或 K8s + Knative。
- 关注成本与运维:测量真实流量下的成本曲线(请求数、并发、运行时间、外部依赖)。
- 可移植性策略:把业务逻辑抽象,尽量分离平台绑定代码,将 provider-specific glue 限制在最外层。
十八、参考(五个关键来源)
- AWS — What is Serverless / AWS Lambda introduction. (Amazon Web Services, Inc.)
- Google Cloud — Serverless architecture(对 serverless 定义与云方案)。(Google Cloud)
- Knative project docs / releases(serverless on Kubernetes)。(Knative)
- AWS Lambda implementation notes / Firecracker & runtime isolation(冷启动、microVM)。(维基百科)
- 学术/综述对 serverless 的深入分析(利弊、安全与研究方向)。(ACM通讯)
本文来自博客园,作者:NeoLshu,转载请注明原文链接:https://www.cnblogs.com/neolshu/p/19513679

浙公网安备 33010602011771号