2、Serverless计算基础:Serverless定义、FaaS与BaaS、主流云厂商Serverless产品、冷启动与热启动

好,咱们正式开始聊Serverless。说实话,这个概念刚出来那会儿,我也挺懵的。什么叫“无服务器”?服务器明明就在那儿跑着,怎么就无了?

其实说白了,Serverless不是真的没有服务器,而是你不需要关心服务器了。你只管写代码、配事件,剩下的——扩容、打补丁、监控、日志,云厂商全给你包了。我个人习惯把Serverless理解成“按需计算 + 全托管”。你想想看,这跟租房子有点像:你不用管水管修不修、墙要不要刷,住进去能用就行。

2.1 Serverless的官方定义

CNCF(云原生计算基金会)给过一个定义:Serverless 是一种构建和运行应用程序的方式,它让开发者完全不用关心底层基础设施。核心特征有两个:

  • 自动弹性伸缩:从0到成千上万并发,系统自己搞定。
  • 按实际使用计费:代码不跑的时候,一分钱不花。

嗯,这里要注意一点:Serverless ≠ 没有服务器。它只是把服务器的复杂性抽象掉了。你在本地写一个函数,部署到云端,触发执行,完事。至于这个函数跑在哪个物理机上、内存够不够、要不要预热——这些都不归你管。

核心观点: Serverless 是一种“关注点分离”的极致体现。你把精力放在业务逻辑上,云厂商负责让代码跑起来。

2.2 FaaS 与 BaaS:Serverless的两大支柱

聊Serverless,绕不开两个词:FaaS 和 BaaS。我刚开始学的时候也搞混过,后来在项目里踩了坑才真正分清楚。

2.2.1 FaaS(函数即服务)

FaaS 就是让你写一个函数,上传到云端,然后给它绑定一个触发器。比如用户上传了一张图片,自动触发一个缩略图生成函数。这就是FaaS的典型场景。

我在项目中遇到过一个问题:一个函数处理时间太长,超过了平台默认的超时限制(比如15分钟)。结果函数被强制终止,数据丢了。后来我学乖了,把长任务拆成多个短函数,用事件链串联起来。

// 一个简单的FaaS函数示例(Node.js)
exports.handler = async (event) => {
  // event 里包含了触发事件的数据
  const imageUrl = event.Records[0].s3.object.key;
  console.log(`处理图片: ${imageUrl}`);
  // 执行缩略图生成逻辑
  return { statusCode: 200, body: 'OK' };
};

避坑指南: 我曾经把一个需要跑5分钟的数据清洗任务直接写成FaaS函数,结果超时了。后来改成用Step Functions编排多个短函数,问题就解决了。记住:FaaS适合短小精悍的任务,别让它干重活。

2.2.2 BaaS(后端即服务)

BaaS 就更“偷懒”了。它把后端通用的能力直接封装成服务给你用。比如用户认证、数据库、对象存储、消息队列。你不需要自己搭Redis、不用自己写登录逻辑,直接调API就行。

举个例子:你想做一个图片分享App。用BaaS的话,用户注册直接调Auth API,图片存到对象存储,元数据写进云数据库。整个后端你可能一行服务器代码都没写,但功能全有了。

对比维度 FaaS BaaS
核心形态 运行你的代码(函数) 提供现成的后端能力
典型产品 AWS Lambda, 阿里云函数计算 Auth0, Firebase, 云数据库
开发者控制力 高(自己写逻辑) 低(配置为主)
适用场景 自定义业务逻辑处理 快速集成通用能力

2.3 主流云厂商的Serverless产品

现在几乎每家云厂商都有自己的Serverless产品线。我挑几个我用过的、比较有代表性的说说。

2.3.1 AWS Lambda

Lambda 算是Serverless的鼻祖了。2014年推出,到现在生态最成熟。支持的语言多(Node.js、Python、Java、Go、.NET……),跟AWS其他服务(S3、DynamoDB、API Gateway)集成得特别好。

我个人习惯用Lambda做数据ETL的轻量处理。比如每天凌晨从S3拉日志,清洗后写入Elasticsearch。代码量不大,但省了一台EC2的钱。

2.3.2 阿里云函数计算(FC)

国内用得最多的Serverless产品之一。跟阿里云生态绑定很深,比如OSS、表格存储、日志服务。我去年帮一个客户做电商促销活动,后端全部跑在FC上。双11那天流量峰值冲到平时100倍,FC自动扩容,一个请求都没丢。

注意: 阿里云FC的冷启动时间比Lambda稍长,尤其是Java运行时。建议用Node.js或Python,或者开启预留实例。

2.3.3 Google Cloud Functions & Cloud Run

Google的Serverless产品线分两条:Cloud Functions(纯FaaS)和Cloud Run(基于容器的Serverless)。Cloud Run 我特别喜欢,因为它可以跑任意语言写的HTTP服务,只要打包成容器镜像就行。灵活性比纯FaaS高不少。

2.3.4 腾讯云云函数(SCF)

腾讯云的SCF跟微信生态结合得很好。如果你要做微信小程序的后端,SCF几乎是首选。触发方式支持微信消息、API网关、定时任务等。我在做一个小程序投票系统时,后端全用SCF + 云数据库,开发周期缩短了60%。

2.4 冷启动与热启动

好,终于聊到重点了。冷启动和热启动,是Serverless里最让人头疼的问题之一。你想想看,一个函数如果很久没被调用,云平台会把它的实例回收掉。等下一个请求来了,得重新下载代码、初始化运行时、执行你的初始化逻辑——这个过程就是冷启动。

热启动就简单了:实例还在,直接复用,响应时间通常在毫秒级。

2.4.1 为什么会冷启动?

说白了,云厂商为了省钱。如果每个函数都一直热着,那跟长期租服务器有什么区别?Serverless的计费模型就是“用多少付多少”,所以空闲时回收实例是必然的。

冷启动的时间受几个因素影响:

  • 运行时类型:Node.js、Python启动快(几十毫秒),Java、C#启动慢(几百毫秒到几秒)。
  • 代码包大小:包越大,下载越慢。我见过有人把整个node_modules都打进去,冷启动直接飙到3秒。
  • 初始化逻辑:比如建立数据库连接、加载配置文件。这些如果在函数外面做,每次冷启动都要跑一遍。
// 不好的写法:每次冷启动都创建数据库连接
exports.handler = async (event) => {
  const db = await createConnection(); // 冷启动时执行
  // ...
};

// 好的写法:连接复用
let db;
exports.handler = async (event) => {
  if (!db) {
    db = await createConnection(); // 只在第一次冷启动时执行
  }
  // ...
};

避坑指南: 我曾经在函数里用全局变量缓存了一个大的配置文件(2MB),结果每次冷启动都要重新加载。后来改成从对象存储按需读取,冷启动时间从1.2秒降到了200毫秒。记住:全局变量在热启动时是复用的,但冷启动时一切归零。

2.4.2 如何应对冷启动?

冷启动没法完全消除,但可以优化。我常用的几个方法:

  • 预留实例:设置一定数量的常驻实例,永远热着。适合对延迟敏感的核心接口。
  • 定时预热:写一个定时任务,每隔几分钟调用一次函数,保持实例活跃。但要注意,云平台可能会检测到这种“假请求”并限制。
  • 选择轻量运行时:Node.js、Python、Go 的冷启动远快于 Java、C#。
  • 精简代码包:只打包必要的依赖,去掉开发工具、文档、测试文件。
优化手段 效果 成本
预留实例 彻底消除冷启动 高(按实例时长付费)
定时预热 大部分时间热启动 低(少量调用费用)
轻量运行时 冷启动时间缩短80% 无额外费用
精简代码包 冷启动时间缩短30%-50% 无额外费用

嗯,这里要提醒一句:别过度优化。如果你的函数调用频率不高(比如每天几次),冷启动多等一两秒完全能接受。只有对延迟敏感的场景(比如用户点击后立即响应),才值得花精力去优化冷启动。

好,这一章的内容就到这儿。Serverless的基础概念、FaaS与BaaS的区别、主流产品、冷启动问题,咱们都聊透了。下一章我会深入讲事件驱动架构的核心模式,到时候咱们再细聊。