
无服务器架构模式
何时使用无服务器
适合的场景:
- 事件驱动型工作负载(图片处理、通知)
- 不可预测的流量(负载变化)
- 批处理作业
- Webhooks 和集成
- 低流量 API
不适合的场景:
- 长时间运行的处理(>15 分钟)
- 高流量 API(大规模时成本高)
- 有状态应用
- 延迟敏感型(冷启动)
- GPU 工作负载

函数组合模式
事件驱动管道
// S3 -> Lambda -> SQS -> Lambda -> DynamoDB
// 每个函数只做一件事
// 图片上传到 S3
export const onImageUpload: S3Handler = async (event) => {
for (const record of event.Records) {
const bucket = record.s3.bucket.name;
const key = record.s3.object.key;
// 发送到处理队列(解耦)
await sqs.sendMessage({
QueueUrl: process.env.PROCESSING_QUEUE_URL!,
MessageBody: JSON.stringify({ bucket, key }),
}).promise();
}
};
// 从 SQS 处理
export const processImage: SQSHandler = async (event) => {
for (const record of event.Records) {
const { bucket, key } = JSON.parse(record.body);
await resizeAndOptimize(bucket, key);
await storeMetadata(bucket, key);
}
};

使用 Step Functions 的 Saga 模式
{
"Comment": "订单处理 saga",
"StartAt": "ValidateOrder",
"States": {
"ValidateOrder": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123:function:validateOrder",
"Next": "ChargePayment",
"Catch": [{ "ErrorEquals": ["ValidationError"], "Next": "OrderFailed" }]
},
"ChargePayment": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123:function:chargePayment",
"Next": "ReserveInventory",
"Catch": [{ "ErrorEquals": ["PaymentFailed"], "Next": "OrderFailed" }]
},
"ReserveInventory": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123:function:reserveInventory",
"Next": "OrderComplete"
},
"OrderComplete": { "Type": "Succeed" },
"OrderFailed": { "Type": "Fail" }
}
}
冷启动缓解
// 1. 预置并发(AWS)
// 在 serverless.yml 中:
// provisionedConcurrency: 5 # 始终保持实例温暖
// 2. 定时预热
export const warmup: ScheduledHandler = async () => {
// 此函数每 5 分钟运行一次以保持 Lambda 温暖
return { statusCode: 200, body: 'warmed' };
};
// 3. 最小化包大小
// 使用 esbuild 打包,摇树优化未使用的模块
// 避免导入整个 AWS SDK - 使用 v3 模块化客户端:
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
// 不要:import AWS from 'aws-sdk';
// 4. 将初始化放在处理函数外部
const client = new DynamoDBClient({ region: 'us-east-1' }); // 在多次调用间复用
export const handler = async (event: APIGatewayEvent) => { /* ... */ };

无状态设计模式
// 问题:在内存中存储状态(冷启动时丢失)
const cache = new Map<string, User>(); // 不好!在调用间丢失
// 解决方案 1:外部缓存
async function getUser(id: string): Promise<User> {
return redis.getOrSet(`user:${id}`, () => db.findUser(id), 300);
}
// 解决方案 2:通过事件传递状态
export const handler = async (event: { userId: string; sessionToken: string }) => {
// 所有需要的状态来自事件
const user = await validateToken(event.sessionToken);
return processRequest(user, event);
};
// 解决方案 3:使用 DynamoDB 实现分布式状态
const session = await dynamodb.getItem({ TableName: 'sessions', Key: { id: { S: sessionId } } });
成本优化
// 使用 ARM64(Graviton)可节省约 20% 成本
// serverless.yml: architecture: arm64
// 合理调整内存大小(更多内存 = 更多 CPU + 成本)
// 分析实际内存使用情况:
export const handler = async () => {
const used = process.memoryUsage().heapUsed / 1024 / 1024;
console.log(`Memory used: ${Math.round(used)}MB`);
// 将 Lambda 内存设置为实际使用量的约 1.5 倍
};
// 批量处理 SQS 消息以减少调用次数
// SQS 触发器设置批处理大小为 10:
export const batchHandler: SQSHandler = async (event) => {
await Promise.all(event.Records.map(r => processRecord(JSON.parse(r.body))));
// 1 次调用处理 10 条消息,而不是 10 次调用
};
无服务器架构适用于事件驱动、可变工作负载,但需要重新思考传统架构。