我们公司把几个业务迁移到了Serverless架构,踩了不少坑,也积累了一些经验。
最开始,我们对Serverless充满了期待,觉得它能解决所有问题。但真正落地的时候,才发现有很多细节需要注意。本文分享Serverless的落地案例和配置详解,从基础到高级,包括函数计算配置、API网关配置、数据库配置、事件触发、冷启动优化、成本优化、监控告警,以及踩过的坑和经验总结。
一、什么是Serverless
1. 概念
Serverless,直译是"无服务器",但不是真的没有服务器,而是开发者不需要关心服务器。
开发者只需要写代码,部署到Serverless平台,平台会自动:
- 分配资源
- 弹性伸缩
- 负载均衡
- 容错恢复
- 计费(按实际使用量计费)
Serverless的核心是:按需执行,按用计费,无需运维。
2. 核心组成
Serverless架构,主要由两部分组成:
- FaaS(Function as a Service,函数即服务):把代码写成函数,按需执行
- BaaS(Backend as a Service,后端即服务):数据库、存储、消息队列等托管服务
常见的Serverless平台:
- 阿里云函数计算
- 腾讯云SCF
- AWS Lambda
- 华为云FunctionGraph
- 开源:OpenFaaS、Knative
3. 优势
Serverless的优势:
- 无需运维:不用管服务器,专注写代码
- 弹性伸缩:自动扩缩容,应对流量波动
- 成本低:按实际使用量计费,不用不花钱
- 开发快:专注业务逻辑,快速上线
- 高可用:平台保证可用性和容错
二、落地案例一:图片处理服务
1. 业务背景
我们有一个图片处理服务,用户上传图片后,需要生成不同尺寸的缩略图。
传统架构:
- 买几台服务器,部署图片处理服务
- 高峰期不够用,低峰期浪费
- 需要自己运维
Serverless架构:
- 用户上传图片到对象存储
- 对象存储触发函数
- 函数处理图片,生成缩略图
- 处理完,函数自动释放
2. 配置详解
函数配置:
functions:
image-resize:
handler: index.handler
runtime: nodejs14
memory: 512MB
timeout: 30s
environment:
OUTPUT_BUCKET: my-output-bucket
triggers:
- type: oss
bucket: my-input-bucket
events:
- oss:ObjectCreated:*关键配置说明:
memory: 512MB:图片处理需要一定内存,512MB比较合适。内存越大,CPU越强,但费用越高。timeout: 30s:图片处理一般几秒到几十秒,30秒够用。oss trigger:对象存储触发,上传图片自动执行函数。
3. 代码示例
const sharp = require('sharp');
const OSS = require('ali-oss');
const client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: process.env.ACCESS_KEY_ID,
accessKeySecret: process.env.ACCESS_KEY_SECRET,
bucket: process.env.OUTPUT_BUCKET
});
exports.handler = async (event, context) => {
const evt = JSON.parse(event);
const objectName = evt.events[0].oss.object.key;
// 下载原图
const result = await client.get(objectName);
// 生成缩略图
const sizes = [100, 200, 400, 800];
for (const size of sizes) {
const buffer = await sharp(result.content)
.resize(size)
.toFormat('webp')
.toBuffer();
await client.put(`thumb/${size}/${objectName}`, buffer);
}
return 'success';
};4. 踩过的坑
- 冷启动:第一次调用,函数需要初始化,延迟高。解决:预留实例,或者用 provisioned concurrency。
- 依赖包大:sharp依赖很大,部署包超过限制。解决:用层(Layer)管理依赖,或者用容器镜像。
- 超时:大图片处理时间长,超时。解决:增加超时时间,或者异步处理。
- 并发限制:大量图片同时上传,并发不够。解决:申请提高并发限制,或者用消息队列削峰。
三、落地案例二:API后端服务
1. 业务背景
我们有一个小程序的后端API,用Serverless架构。
传统架构:
- 买服务器,部署Node.js服务
- 需要自己做负载均衡、弹性伸缩
- 流量小的时候浪费,流量大的时候不够用
Serverless架构:
- API网关接收请求
- 转发到函数
- 函数处理业务逻辑
- 返回结果
2. 配置详解
函数配置:
functions:
api:
handler: app.handler
runtime: nodejs14
memory: 256MB
timeout: 10s
environment:
DB_HOST: process.env.DB_HOST
DB_USER: process.env.DB_USER
DB_PASSWORD: process.env.DB_PASSWORD
triggers:
- type: api_gateway
methods:
- GET
- POST
paths:
- /api/*API网关配置:
- 协议:HTTP/HTTPS
- 认证方式:API Key 或 JWT
- 限流:每秒100次
- 超时:10秒
- 跨域:配置CORS
3. 代码示例(Express适配)
const express = require('express');
const serverless = require('serverless-http');
const mysql = require('mysql2/promise');
const app = express();
app.use(express.json());
let pool;
async function getPool() {
if (!pool) {
pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: 'mydb',
connectionLimit: 10
});
}
return pool;
}
app.get('/api/users', async (req, res) => {
const pool = await getPool();
const [rows] = await pool.query('SELECT * FROM users LIMIT 100');
res.json(rows);
});
app.post('/api/users', async (req, res) => {
const pool = await getPool();
const { name, email } = req.body;
const [result] = await pool.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
);
res.json({ id: result.insertId });
});
module.exports.handler = serverless(app);4. 踩过的坑
- 数据库连接:函数每次执行都新建连接,数据库连接数爆炸。解决:用连接池,在函数外初始化,复用连接。
- 冷启动:API请求延迟高。解决:预留实例,或者用单函数多路由,减少函数数量。
- 状态管理:函数是无状态的,不能用内存存状态。解决:用Redis或数据库存状态。
- 文件上传:API网关有请求大小限制。解决:大文件用对象存储,API只传URL。
四、落地案例三:定时任务
1. 业务背景
我们有一些定时任务,比如:
- 每天凌晨统计数据
- 每小时同步数据
- 每周生成报表
传统架构:
- 买一台服务器,跑crontab
- 服务器不能关,浪费资源
- 需要自己保证任务执行成功
Serverless架构:
- 用定时触发器
- 到时间自动执行函数
- 执行完自动释放
- 平台保证执行成功
2. 配置详解
functions:
daily-report:
handler: report.handler
runtime: python3
memory: 1024MB
timeout: 300s
triggers:
- type: timer
name: daily-report
cron: '0 0 2 * * *' # 每天凌晨2点
payload: '{"type": "daily"}'
hourly-sync:
handler: sync.handler
runtime: nodejs14
memory: 256MB
timeout: 60s
triggers:
- type: timer
name: hourly-sync
cron: '0 0 * * * *' # 每小时3. 踩过的坑
- 超时:大数据量统计,超时。解决:增加超时时间,或者分批处理。
- 失败重试:任务失败了,需要重试。解决:配置重试次数,或者自己实现重试逻辑。
- 幂等性:任务重复执行,数据重复。解决:保证任务幂等,用唯一标识去重。
- 依赖外部服务:外部服务挂了,任务失败。解决:加容错,失败告警,手动重试。
五、高级配置
1. 冷启动优化
冷启动是Serverless最大的痛点。优化方法:
- 预留实例:提前初始化一些实例,随时待命。费用高,但延迟低。
- 单函数多路由:把多个API放到一个函数里,减少函数数量,提高复用率。
- 减少部署包大小:只打包必要的依赖,用层(Layer)管理公共依赖。
- 初始化优化:把重的初始化逻辑放到函数外,只执行一次。
- 运行时选择:选择启动快的运行时,如Node.js、Python,避免Java、.NET。
- 容器镜像:用容器镜像部署,启动更快,环境更一致。
2. 成本优化
Serverless按用计费,但用不好也会很贵。
- 内存优化:内存越大,CPU越强,费用越高。找到性能和成本的平衡点。
- 超时优化:超时时间不要设太大,避免异常函数占用资源。
- 并发控制:限制最大并发,避免异常流量导致费用暴增。
- 日志优化:日志量大了也收费,合理设置日志级别。
- 监控费用:设置费用告警,避免意外扣费。
3. 数据库连接优化
Serverless函数和数据库配合,最容易出问题的是连接数。
- 连接池:在函数外初始化连接池,复用连接。
- 数据库代理:用数据库代理(如RDS Proxy),管理连接池。
- Serverless数据库:用支持Serverless的数据库,如Aurora Serverless。
- 缓存:用Redis缓存,减少数据库查询。
- 批量操作:减少数据库请求次数,批量操作。
4. 监控告警
Serverless的监控很重要。
- 调用次数:监控函数调用次数,异常增长要告警
- 执行时间:监控函数执行时间,超时要告警
- 错误率:监控错误率,超过阈值要告警
- 冷启动次数:监控冷启动,优化延迟
- 费用:监控费用,异常扣费要告警
- 并发:监控并发,接近上限要告警
六、Serverless的适用场景
Serverless不是银弹,不是所有场景都适合。
适合的场景:
- 事件驱动:图片处理、文件处理、消息处理
- API后端:小程序、移动端后端
- 定时任务:数据统计、报表生成
- 流量波动大:活动页、促销系统
- 低频请求:管理后台、内部工具
- 原型验证:快速验证想法
不适合的场景:
- 长连接:WebSocket、长轮询
- 高性能计算:需要持续高性能
- 大文件处理:超过超时限制
- 状态ful应用:需要持续保持状态
- 对延迟极度敏感:冷启动延迟不可接受
- 高并发稳态:一直高并发,Serverless反而贵
七、经验总结
1. 从小处着手
不要一上来就把所有业务都迁到Serverless。
- 先选一个合适的场景,做试点
- 试点成功了,再推广
- 积累经验,再迁移核心业务
2. 做好监控
Serverless的监控,比传统架构更重要。
- 因为你看不到服务器,只能靠监控
- 出了问题,要靠监控定位
- 费用异常,要靠监控发现
从第一天开始,就要做好监控和告警。
3. 注意冷启动
冷启动是Serverless的通病,要提前考虑。
- 对延迟敏感的业务,用预留实例
- 尽量减少函数数量,提高复用率
- 优化初始化逻辑,减少冷启动时间
4. 数据库是关键
Serverless和数据库配合,最容易出问题。
- 连接数管理
- 连接池复用
- 数据库代理
- 缓存
数据库设计好了,Serverless才能用好。
5. 成本要监控
Serverless按用计费,用不好会很贵。
- 设置费用告警
- 定期分析费用
- 优化内存和超时
- 控制并发
不要等账单出来了才发现超支了。
6. 不要盲目跟风
Serverless很火,但不是所有业务都适合。
- 先评估业务场景
- 做技术验证
- 算清楚成本
- 再决定要不要用
不要为了用Serverless而用Serverless。
八、写在最后
Serverless,是云计算的一个重要方向。它让开发者不用关心服务器,专注业务逻辑,快速上线。
但它也不是银弹,有自己的适用场景和局限性。冷启动、数据库连接、成本控制、监控告警,这些都是落地时需要注意的问题。
我们公司用Serverless做了图片处理、API后端、定时任务等几个业务,整体效果不错。运维少了,弹性好了,成本也降了。但也踩了不少坑,花了不少时间优化。
2022年了,Serverless越来越成熟,工具越来越多,门槛越来越低。如果你有合适的业务场景,可以试试Serverless,它可能会给你带来惊喜。
最后,用一句话总结:"Serverless,不是银弹,但在合适的场景下,能让你事半功倍。从小处着手,做好监控,注意冷启动和数据库,控制成本,不要盲目跟风。"
愿你的Serverless落地,少踩坑,多顺利。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录