
AWS Lambda 最佳实践
冷启动优化
// 错误:在 handler 内部初始化连接
export const handler = async (event: APIGatewayEvent) => {
const db = await createDatabaseConnection(); // 每次调用都冷启动!
const result = await db.query('SELECT ...');
return result;
};
// 正确:在 handler 外部初始化(跨调用复用)
const db = await createDatabaseConnection(); // 每个容器只运行一次
export const handler = async (event: APIGatewayEvent) => {
const result = await db.query('SELECT ...');
return result;
};
// 使用适当大小的连接池
// Lambda 的 CPU/内存有限,小池子即可
const pool = new Pool({
host: process.env.DB_HOST,
max: 5, // Lambda 的小连接池
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});

错误处理
import { APIGatewayProxyHandler } from 'aws-lambda';
export const handler: APIGatewayProxyHandler = async (event) => {
try {
const body = JSON.parse(event.body ?? '{}');
const result = await processRequest(body);
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result),
};
} catch (err) {
console.error('Handler error:', { err, event }); // CloudWatch
if (err instanceof ValidationError) {
return {
statusCode: 400,
body: JSON.stringify({ error: err.message }),
};
}
// 不要暴露内部错误
return {
statusCode: 500,
body: JSON.stringify({ error: 'Internal server error' }),
};
}
};

环境变量与密钥
import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm';
// 在调用之间缓存密钥
const secretCache = new Map<string, { value: string; expiresAt: number }>();
async function getSecret(name: string): Promise<string> {
const cached = secretCache.get(name);
if (cached && cached.expiresAt > Date.now()) {
return cached.value;
}
const ssm = new SSMClient({ region: process.env.AWS_REGION });
const response = await ssm.send(
new GetParameterCommand({ Name: name, WithDecryption: true })
);
const value = response.Parameter!.Value!;
secretCache.set(name, {
value,
expiresAt: Date.now() + 5 * 60 * 1000, // 缓存 5 分钟
});
return value;
}

Lambda 层
# serverless.yml
service: my-api
provider:
name: aws
runtime: nodejs20.x
region: us-east-1
layers:
dependencies:
path: layers/dependencies
name: api-dependencies
description: Node.js dependencies
compatibleRuntimes:
- nodejs20.x
functions:
api:
handler: src/handler.handler
layers:
- !Ref DependenciesLambdaLayer
events:
- http:
path: /api/{proxy+}
method: ANY
结构化日志
function createLogger(context: LambdaContext) {
return {
info: (message: string, data?: object) => {
console.log(JSON.stringify({
level: 'INFO',
message,
requestId: context.awsRequestId,
...data,
}));
},
error: (message: string, err?: unknown, data?: object) => {
console.error(JSON.stringify({
level: 'ERROR',
message,
requestId: context.awsRequestId,
error: err instanceof Error ? { message: err.message, stack: err.stack } : err,
...data,
}));
},
};
}
export const handler = async (event: APIGatewayEvent, context: LambdaContext) => {
const logger = createLogger(context);
logger.info('Request received', { path: event.path, method: event.httpMethod });
// ...
};
成本优化
// SAM template with reserved concurrency
// template.yaml
// Resources:
// ApiFunction:
// Type: AWS::Serverless::Function
// Properties:
// ReservedConcurrentExecutions: 100 # 防止失控成本
// MemorySize: 256 # 从低开始,分析后调整
// Timeout: 29 # 小于 API GW 30s 超时
// 使用自定义指标监控
import { CloudWatchClient, PutMetricDataCommand } from '@aws-sdk/client-cloudwatch';
async function recordMetric(name: string, value: number, unit: string): Promise<void> {
const cloudwatch = new CloudWatchClient({ region: process.env.AWS_REGION });
await cloudwatch.send(new PutMetricDataCommand({
Namespace: 'MyApp',
MetricData: [{
MetricName: name,
Value: value,
Unit: unit,
Dimensions: [{ Name: 'Environment', Value: process.env.ENVIRONMENT! }],
}],
}));
}
Lambda 按毫秒计费,奖励快速、精简的函数——优化启动时间和内存。