name: aws-lambda-functions description: 创建并部署无服务器函数,使用AWS Lambda和事件源、权限、层以及环境配置。适用于事件驱动计算而无需管理服务器。
AWS Lambda 函数
概览
AWS Lambda 允许您无需预置或管理服务器即可运行代码。使用事件驱动触发器构建无服务器应用程序,仅支付消耗的计算时间,并根据工作负载自动扩展。
使用场景
- API端点和Webhook
- 计划批处理作业和数据处理
- 实时文件处理(S3上传)
- 事件驱动工作流(SNS、SQS)
- 微服务和后端API
- 数据转换和ETL作业
- IoT和传感器数据处理
- WebSocket连接
实施示例
1. 使用AWS CLI的基本Lambda函数
# 创建Lambda执行角色
aws iam create-role \
--role-name lambda-execution-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# 附加基本执行策略
aws iam attach-role-policy \
--role-name lambda-execution-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
# 从ZIP创建函数
zip function.zip index.js
aws lambda create-function \
--function-name my-function \
--runtime nodejs18.x \
--role arn:aws:iam::ACCOUNT:role/lambda-execution-role \
--handler index.handler \
--zip-file fileb://function.zip \
--timeout 30 \
--memory-size 256 \
--environment Variables={ENV=production,DB_HOST=db.example.com}
# 调用函数
aws lambda invoke \
--function-name my-function \
--payload '{"name":"John","age":30}' \
response.json
2. 使用Node.js的Lambda函数
// index.js
exports.handler = async (event) => {
console.log('Event:', JSON.stringify(event));
try {
// 解析不同的事件源
const body = typeof event.body === 'string'
? JSON.parse(event.body)
: event.body || {};
// 处理S3事件
if (event.Records && event.Records[0].s3) {
const bucket = event.Records[0].s3.bucket.name;
const key = event.Records[0].s3.object.key;
console.log(`Processing S3 object: ${bucket}/${key}`);
}
// 数据库查询模拟
const results = await queryDatabase(body);
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({
message: 'Success',
data: results
})
};
} catch (error) {
console.error('Error:', error);
return {
statusCode: 500,
body: JSON.stringify({ error: error.message })
};
}
};
async function queryDatabase(params) {
// 模拟数据库调用
return { items: [] };
}
3. 使用Terraform的Lambda部署
# main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
# Lambda执行角色
resource "aws_iam_role" "lambda_role" {
name = "lambda-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}]
})
}
# CloudWatch日志策略
resource "aws_iam_role_policy_attachment" "lambda_logs" {
role = aws_iam_role.lambda_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
# S3 Lambda层(依赖项)
resource "aws_lambda_layer_version" "dependencies" {
filename = "layer.zip"
layer_name = "nodejs-dependencies"
compatible_runtimes = ["nodejs18.x"]
}
# Lambda函数
resource "aws_lambda_function" "api_handler" {
filename = "lambda.zip"
function_name = "api-handler"
role = aws_iam_role.lambda_role.arn
handler = "index.handler"
runtime = "nodejs18.x"
timeout = 30
memory_size = 256
layers = [aws_lambda_layer_version.dependencies.arn]
environment {
variables = {
STAGE = "production"
DB_HOST = var.database_host
}
}
depends_on = [aws_iam_role_policy_attachment.lambda_logs]
}
# API网关触发器
resource "aws_lambda_permission" "api_gateway" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.api_handler.function_name
principal = "apigateway.amazonaws.com"
}
# S3触发器
resource "aws_lambda_permission" "s3_trigger" {
statement_id = "AllowS3Invoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.api_handler.function_name
principal = "s3.amazonaws.com"
source_arn = aws_s3_bucket.upload_bucket.arn
}
resource "aws_s3_bucket_notification" "bucket_notification" {
bucket = aws_s3_bucket.upload_bucket.id
depends_on = [aws_lambda_permission.s3_trigger]
lambda_function {
lambda_function_arn = aws_lambda_function.api_handler.arn
events = ["s3:ObjectCreated:*"]
filter_prefix = "uploads/"
filter_suffix = ".jpg"
}
}
4. 使用SAM(Serverless Application Model)的Lambda
# template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 30
MemorySize: 256
Runtime: nodejs18.x
Tracing: Active
Parameters:
Environment:
Type: String
Default: dev
AllowedValues: [dev, prod]
Resources:
# Lambda函数
MyFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub '${Environment}-my-function'
CodeUri: src/
Handler: index.handler
Architectures:
- x86_64
Environment:
Variables:
STAGE: !Ref Environment
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref DataTable
- S3CrudPolicy:
BucketName: !Ref DataBucket
Events:
ApiEvent:
Type: Api
Properties:
Path: /api/{proxy+}
Method: ANY
RestApiId: !Ref MyApi
S3Upload:
Type: S3
Properties:
Bucket: !Ref DataBucket
Events: s3:ObjectCreated:*
Filter:
S3Key:
Rules:
- Name: prefix
Value: uploads/
# DynamoDB表
DataTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Sub '${Environment}-data'
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
# S3桶
DataBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub '${Environment}-data-${AWS::AccountId}'
VersioningConfiguration:
Status: Enabled
# API网关
MyApi:
Type: AWS::Serverless::Api
Properties:
Name: !Sub '${Environment}-api'
StageName: !Ref Environment
Cors:
AllowMethods: "'*'"
AllowHeaders: "'Content-Type,Authorization'"
AllowOrigin: "'*'"
Outputs:
FunctionArn:
Value: !GetAtt MyFunction.Arn
ApiEndpoint:
Value: !Sub 'https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com'
5. 代码共享的Lambda层
# 创建层目录结构
mkdir -p layer/nodejs/node_modules
cd layer/nodejs
# 安装依赖项
npm install lodash axios moment
# 返回并创建zip
cd ..
zip -r layer.zip .
# 上传层
aws lambda publish-layer-version \
--layer-name shared-utils \
--zip-file fileb://layer.zip \
--compatible-runtimes nodejs18.x
最佳实践
✅ DO
- 使用环境变量进行配置
- 实施适当的错误处理和日志记录
- 优化包大小和依赖项
- 设置适当的超时和内存
- 使用Lambda层共享代码
- 实施并发限制
- 启用X-Ray跟踪以进行调试
- 为关键函数使用预留并发
❌ DON’T
- 在代码中存储敏感数据
- 创建长时间运行的操作(>15分钟)
- 忽略冷启动优化
- 忘记处理并发执行
- 忽略CloudWatch指标
- 无谓地使用太多内存
监控与故障排除
- CloudWatch日志用于应用程序日志记录
- CloudWatch指标用于持续时间、错误、节流
- X-Ray跟踪用于性能分析
- 死信队列用于失败的消息
- 报警用于错误和节流