Serverless(无服务器)是一种云计算模型,让您无需关心服务器即可部署和运行代码——云平台自动分配资源、按需扩缩容,并按实际使用量计费。本文将详细介绍Serverless是什么、FaaS与BaaS的区别、冷启动的工作原理、函数执行生命周期,以及何时应该(或不应该)选择无服务器架构。
需要企业数据解决方案?
自 2019 年起,AlgoData 为企业提供数据工程、分析与 AI 解决方案。
Serverless是什么?
Serverless(无服务器)是一种云计算执行模型,开发者只需编写和部署代码——通常是独立的函数——而服务器的供给、运维和弹性扩缩容完全由云服务商(AWS、GCP、Azure)负责。
"Serverless"这个名称有些误导性:服务器仍然存在,但您不需要管理它们。您无需担心操作系统补丁、安全漏洞修复、负载均衡器配置或磁盘监控。所有这些都从开发者的视野中完全抽象掉了。
Serverless的两个核心特征:
- 无需管理服务器: 云平台自动供给、扩缩容并回收计算资源。
- 按调用付费: 按函数调用次数和实际CPU消耗付费,而非为空闲的服务器容量付费。
Serverless涵盖两大分支:FaaS(函数即服务)和BaaS(后端即服务)。下一节将详细区分这两个概念。
FaaS vs BaaS

虽然两者都属于Serverless范畴,但FaaS和BaaS服务于不同的目的:
FaaS——函数即服务是一种将单个函数部署到云端、由事件驱动调用的模型(HTTP请求、队列消息、定时任务等)。函数执行完毕后,云平台立即回收资源。主要代表:
- AWS Lambda ——最广泛采用的FaaS平台,支持Python、Node.js、Go、Java、Ruby等。
- Google Cloud Functions ——与Firebase和GCP生态深度集成。
- Azure Functions ——与微软服务(Event Hub、Service Bus)强集成。
- Vercel Edge Functions ——针对Next.js和前端场景优化,在离用户最近的边缘节点运行。
BaaS——后端即服务提供开箱即用的后端服务,可直接从前端调用,无需编写服务器代码。主要代表:
- Firebase(Google)——实时数据库、身份认证、文件存储和推送通知。
- Supabase ——带实时订阅、认证和存储的PostgreSQL;开源。
- AWS Amplify ——为前端集成认证(Cognito)、GraphQL(AppSync)和存储(S3)。
核心区别:FaaS让您在服务端运行自定义业务逻辑;BaaS为常见需求提供预构建的基础设施。实际项目中,很多应用会同时使用两者——在同一个应用中使用Firebase Auth(BaaS)和AWS Lambda(FaaS)。
冷启动 vs 热启动

冷启动延迟是采用Serverless时最实际的挑战之一。
**热启动(Warm Start)**发生在函数最近被调用过、其容器仍在云内存中存活时。下一次调用会立即得到服务——延迟仅为处理函数的执行时间,对于简单业务逻辑通常不超过10毫秒。
**冷启动(Cold Start)**发生在以下情况:
- 函数部署后首次被调用。
- 函数空闲时间过长,云平台已回收其容器。
- 流量突增超过当前热实例数量。
冷启动期间,云平台必须完成完整的初始化链:
- 供给容器 ——创建新的隔离执行环境。
- 加载运行时 ——启动解释器、JVM或语言运行时。
- 获取部署包 ——下载并解压您的代码。
- 初始化模块 ——运行模块级初始化代码(导入、数据库连接、配置解析)。
- 执行处理函数 ——最终运行您实际编写的函数。
各运行时典型冷启动时间:
| 运行时 | 冷启动时间 |
|---|---|
| Node.js | ~100–300毫秒 |
| Python | ~100–400毫秒 |
| Go | ~50–200毫秒 |
| Java (JVM) | ~500毫秒–2秒 |
| .NET | ~300毫秒–1秒 |
减少冷启动的策略:
- 预置并发(AWS Lambda Provisioned Concurrency): 保持一定数量的实例始终温热,完全消除冷启动——但会增加额外费用。
- 减小包体积: 删除不必要的依赖,使用Tree-shaking。
- 避免重量初始化: 不在模块作用域中打开数据库连接;使用懒初始化。
- 选择轻量运行时: Go和Node.js的冷启动时间明显短于Java/Spring。
- 定时预热: 使用CloudWatch定时任务每5分钟Ping一次函数以保持温热状态。
执行生命周期:从触发到终止
每次无服务器函数被调用时,都会经历固定的四个阶段:
1. 触发(Trigger) 外部事件触发函数——通过API网关的HTTP请求、来自SQS或Kafka的消息、S3的文件上传或定时Cron事件。云平台接收事件并决定将其分发到哪个实例(热启动或冷启动)。
2. 初始化(Init) 此阶段仅在冷启动时发生。云平台创建执行环境、加载运行时并执行所有模块级代码(处理函数之外的代码)。数据库连接、配置解析和重量导入应放在此处,以便在热调用间复用。
3. 执行(Execute)
您的处理函数被以事件对象和上下文对象作为参数调用。这是您编写的代码,返回结果。在AWS Lambda中,这就是lambda_handler(event, context)。
4. 终止(Terminate) 处理函数返回后,云平台"冻结"执行环境——容器不会立即销毁,而是保留用于潜在的热启动复用。空闲一段时间后(Lambda通常为15–45分钟),云平台才真正回收容器。
代码示例
AWS Lambda(Python)
1import json
2import boto3
3
4# 初始化阶段:执行一次,在热调用间复用
5s3_client = boto3.client('s3')
6
7def lambda_handler(event, context):
8 """
9 Lambda主处理函数。
10 event: 包含触发器数据的字典(HTTP请求、SQS消息等)
11 context: 包含执行元数据的对象(请求ID、剩余超时时间等)
12 """
13 # 从API网关代理事件中读取HTTP方法和路径
14 http_method = event.get('httpMethod', 'GET')
15 path = event.get('path', '/')
16
17 # 业务逻辑
18 if http_method == 'GET' and path == '/hello':
19 body = {
20 'message': '来自AWS Lambda的问候!',
21 'requestId': context.aws_request_id,
22 }
23 status_code = 200
24 else:
25 body = {'error': '未找到'}
26 status_code = 404
27
28 # 按API网关代理集成格式返回HTTP响应
29 return {
30 'statusCode': status_code,
31 'headers': {
32 'Content-Type': 'application/json',
33 'Access-Control-Allow-Origin': '*',
34 },
35 'body': json.dumps(body, ensure_ascii=False),
36 }
Vercel边缘函数(JavaScript)
1// api/hello.js — Vercel Edge Runtime
2// 在距离用户最近的边缘节点运行,延迟低于标准Lambda
3
4export const config = {
5 runtime: 'edge',
6};
7
8export default async function handler(request) {
9 const { searchParams } = new URL(request.url);
10 const name = searchParams.get('name') || '世界';
11
12 // 边缘函数使用Web标准的Request和Response对象
13 return new Response(
14 JSON.stringify({
15 message: `你好,${name}!由Vercel Edge提供支持。`,
16 region: process.env.VERCEL_REGION || 'unknown',
17 }),
18 {
19 status: 200,
20 headers: {
21 'Content-Type': 'application/json',
22 'Cache-Control': 's-maxage=60, stale-while-revalidate',
23 },
24 }
25 );
26}
事件触发器类型
无服务器函数可以由多种不同的事件源触发:
HTTP / API网关 最常见的触发器——API网关接收HTTP请求并以标准化事件对象的形式转发给Lambda。适合REST API、Webhook端点和前端后端(BFF)模式。
消息队列(SQS / Kafka / Pub/Sub) 当队列中有新消息时触发函数。Lambda批量轮询SQS队列并并行处理消息。适合异步任务处理和事件驱动架构。
定时任务(Cron Job) AWS EventBridge Scheduler按Cron计划触发Lambda——例如每天午夜生成营收报告或每周日运行清理任务。完全替代传统服务器上的Crontab。
存储事件(S3 / Cloud Storage) 文件上传到S3存储桶时自动触发函数。广泛用于图片处理流水线——用户上传原始图片→S3触发Lambda→Lambda调整为多个尺寸→保存到CDN存储桶。
数据库流(DynamoDB Streams / Firestore) 每次数据库变更(增/改/删)都会生成触发函数的事件。用于将数据同步到Elasticsearch、发送通知或使缓存失效。
Serverless vs 容器 vs 虚拟机

在设计系统时,以下实用对比矩阵有助于选择正确的计算模型:
| 评估维度 | Serverless | 容器(K8s/ECS) | 虚拟机 |
|---|---|---|---|
| 基础设施管理 | 云全托管 | 管理集群/Pod | 管理完整操作系统 |
| 扩缩容 | 自动、即时 | 自动HPA,需配置 | 手动或Auto Scaling Group |
| 空闲成本 | $0(不运行=不收费) | 为运行中的节点付费 | 虚拟机24/7付费 |
| 冷启动 | 存在(50毫秒–2秒) | 可忽略不计 | 无 |
| 超时限制 | 最长15分钟(Lambda) | 无限制 | 无限制 |
| 有状态 | 否(每次调用独立) | 是(PVC、StatefulSet) | 是 |
| 网络 | 受限,需配置VPC | 灵活 | 完全控制 |
| 运维复杂度 | 最低 | 中等至高 | 最高 |
| 最适合 | 事件驱动、突发流量 | 长期运行服务 | 遗留应用、GPU工作负载 |
何时选择Serverless:
- 间歇性、突发性或不可预测的流量模式。
- 追求高开发效率,不想投入时间运维基础设施。
- 事件驱动任务:图片处理、Webhook、ETL流水线、定时任务。
- 预算有限的MVP或小型微服务。
何时不应选择Serverless:
- 函数需要持续运行超过15分钟。
- 应用需要在请求间保持内存中的状态(有状态)。
- 持续高流量导致成本急剧上升。
- 需要对运行时、网络或GPU进行精细控制。
- 需要亚毫秒级延迟、无法接受冷启动延迟。
真实应用场景
1. 图片缩放流水线 用户上传原始图片→S3触发Lambda→Lambda使用Pillow/Sharp调整为3种尺寸(150px缩略图、600px中等、1200px大图)→保存到S3 CDN存储桶。没有上传时成本接近零;流量突增时自动扩缩容。
2. Webhook处理器 Stripe发送支付Webhook→API网关接收→Lambda验证签名、更新数据库中的订单状态并发送确认邮件。Serverless非常适合,因为Webhook是偶发性的——按实际使用量精确付费。
3. 定时报告任务 EventBridge Scheduler每天早上6点触发Lambda→Lambda查询BigQuery/Redshift,汇总前一天的营收报告→向团队Slack频道发送通知。无需服务器24/7运行,只为每天执行2分钟的任务。

