关于 aws-lambda
用于使用 AWS Lambda 构建和运维无服务器应用的技能,指导开发者处理函数、事件源、层、基于 SAM 的部署及冷启动优化。
主要功能
- 01创建并部署 Lambda 函数
- 02配置事件源映射
- 03构建并发布 Lambda 层
- 04使用 AWS SAM 开发和部署
- 05调整冷启动与并发
适用场景
- 01构建 API Gateway 或函数 URL 端点
- 02处理 SQS、Kinesis 或 DynamoDB 事件
- 03运行定时任务或 webhook 自动化
- 04降低对冷启动敏感的函数延迟
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill aws-lambda安装后在 Claude Code 中输入/aws-lambda确认已加载。
详细介绍
AWS Lambda
使用 AWS Lambda 构建无服务器应用,涵盖函数创建、事件源、层、SAM 模板和冷启动优化。
何时使用此技能
- 构建由 API Gateway、S3、SQS 或 EventBridge 触发的事件驱动型应用
- 无需管理服务器即可运行定时任务(cron)
- 处理来自 Kinesis 或 DynamoDB 的数据流
- 使用 API Gateway 或函数 URL 构建轻量级 API
- 实现 Webhook、Slack 机器人或自动化脚本
- 降低间歇性或突发性工作负载的计算成本
前置条件
- 已安装并配置 AWS CLI v2
- IAM 权限:
lambda:*、iam:PassRole、logs:*、apigateway:*、s3:* - 本地已安装 Python 3.11+、Node.js 20+ 或其他受支持的运行时
- (可选)用于本地开发和部署的 AWS SAM CLI
创建和部署函数
# Create a deployment package
cd my-function
zip -r function.zip app.py
# Create the Lambda function
aws lambda create-function \
--function-name my-api-handler \
--runtime python3.12 \
--handler app.handler \
--role arn:aws:iam::123456789012:role/LambdaExecRole \
--zip-file fileb://function.zip \
--memory-size 256 \
--timeout 30 \
--environment 'Variables={STAGE=production,LOG_LEVEL=INFO}' \
--architectures arm64 \
--tracing-config Mode=Active \
--tags '{"Team":"backend","Environment":"production"}'
# Update function code
aws lambda update-function-code \
--function-name my-api-handler \
--zip-file fileb://function.zip
# Update function configuration
aws lambda update-function-configuration \
--function-name my-api-handler \
--memory-size 512 \
--timeout 60 \
--environment 'Variables={STAGE=production,LOG_LEVEL=WARNING}'
# Publish a version (immutable snapshot)
aws lambda publish-version \
--function-name my-api-handler \
--description "v1.2.0 - added rate limiting"
# Create an alias pointing to the version
aws lambda create-alias \
--function-name my-api-handler \
--name live \
--function-version 3
# Weighted alias for canary deployments (90% v3, 10% v4)
aws lambda update-alias \
--function-name my-api-handler \
--name live \
--function-version 4 \
--routing-config '{"AdditionalVersionWeights":{"3":0.9}}'
函数代码示例
# app.py - API Gateway handler with structured logging
import json
import logging
import os
logger = logging.getLogger()
logger.setLevel(os.environ.get("LOG_LEVEL", "INFO"))
def handler(event, context):
"""Handle API Gateway proxy event."""
logger.info("Request: %s %s", event["httpMethod"], event["path"])
try:
body = json.loads(event.get("body", "{}"))
result = process_request(body)
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json",
"X-Request-Id": context.aws_request_id
},
"body": json.dumps(result)
}
except ValueError as e:
logger.warning("Validation error: %s", e)
return {"statusCode": 400, "body": json.dumps({"error": str(e)})}
except Exception as e:
logger.exception("Unhandled error")
return {"statusCode": 500, "body": json.dumps({"error": "Internal server error"})}
def process_request(body):
return {"message": "OK", "data": body}
# sqs_processor.py - SQS batch processor with partial failure reporting
import json
import logging
logger = logging.getLogger()
logger.setLevel("INFO")
def handler(event, context):
"""Process SQS messages with partial batch failure reporting."""
failed_ids = []
for record in event["Records"]:
try:
body = json.loads(record["body"])
logger.info("Processing message: %s", record["messageId"])
process_message(body)
except Exception as e:
logger.error("Failed message %s: %s", record["messageId"], e)
failed_ids.append(record["messageId"])
# Return failed items so only those get retried
return {
"batchItemFailures": [
{"itemIdentifier": msg_id} for msg_id in failed_ids
]
}
def process_message(body):
pass # your logic here
Lambda 层
# Build a layer for Python dependencies
mkdir -p layer/python
pip install requests boto3-stubs -t layer/python/
cd layer
zip -r ../my-layer.zip python/
# Publish the layer
aws lambda publish-layer-version \
--layer-name common-deps \
--description "Shared Python dependencies" \
--zip-file fileb://my-layer.zip \
--compatible-runtimes python3.11 python3.12 \
--compatible-architectures arm64 x86_64
# Attach layer to a function
aws lambda update-function-configuration \
--function-name my-api-handler \
--layers "arn:aws:lambda:us-east-1:123456789012:layer:common-deps:1"
# List available layers
aws lambda list-layers --compatible-runtime python3.12
事件源映射
# SQS trigger with batch processing
aws lambda create-event-source-mapping \
--function-name sqs-processor \
--event-source-arn arn:aws:sqs:us-east-1:123456789012:my-queue \
--batch-size 10 \
--maximum-batching-window-in-seconds 5 \
--function-response-types ReportBatchItemFailures
# DynamoDB Streams trigger
aws lambda create-event-source-mapping \
--function-name stream-processor \
--event-source-arn arn:aws:dynamodb:us-east-1:123456789012:table/my-table/stream/2026-01-01T00:00:00.000 \
--batch-size 100 \
--starting-position LATEST \
--maximum-retry-attempts 3 \
--bisect-batch-on-function-error \
--destination-config '{"OnFailure":{"Destination":"arn:aws:sqs:us-east-1:123456789012:dlq"}}'
# S3 event notification (via Lambda permission + S3 config)
aws lambda add-permission \
--function-name image-processor \
--statement-id s3-trigger \
--action lambda:InvokeFunction \
--principal s3.amazonaws.com \
--source-arn arn:aws:s3:::my-uploads-bucket \
--source-account 123456789012
aws s3api put-bucket-notification-configuration \
--bucket my-uploads-bucket \
--notification-configuration '{
"LambdaFunctionConfigurations": [{
"LambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:image-processor",
"Events": ["s3:ObjectCreated:*"],
"Filter": {"Key": {"FilterRules": [{"Name": "suffix", "Value": ".jpg"}]}}
}]
}'
# Schedule with EventBridge (cron)
aws events put-rule \
--name daily-cleanup \
--schedule-expression "cron(0 2 * * ? *)" \
--state ENABLED
aws lambda add-permission \
--function-name daily-cleanup \
--statement-id eventbridge \
--action lambda:InvokeFunction \
--principal events.amazonaws.com \
--source-arn arn:aws:events:us-east-1:123456789012:rule/daily-cleanup
aws events put-targets \
--rule daily-cleanup \
--targets '[{"Id":"1","Arn":"arn:aws:lambda:us-east-1:123456789012:function:daily-cleanup"}]'
函数 URL(无需 API Gateway)
# Create a function URL (public HTTPS endpoint)
aws lambda create-function-url-config \
--function-name my-api-handler \
--auth-type NONE \
--cors '{
"AllowOrigins": ["https://myapp.com"],
"AllowMethods": ["GET", "POST"],
"AllowHeaders": ["Content-Type"],
"MaxAge": 86400
}'
# Grant public invoke for function URL
aws lambda add-permission \
--function-name my-api-handler \
--statement-id function-url-public \
--action lambda:InvokeFunctionUrl \
--principal "*" \
--function-url-auth-type NONE
冷启动优化
# Enable provisioned concurrency to eliminate cold starts
aws lambda put-provisioned-concurrency-config \
--function-name my-api-handler \
--qualifier live \
--provisioned-concurrent-executions 10
# Set reserved concurrency (throttle limit)
aws lambda put-function-concurrency \
--function-name my-api-handler \
--reserved-concurrent-executions 100
# Enable SnapStart for Java functions (near-zero cold starts)
aws lambda update-function-configuration \
--function-name my-java-handler \
--snap-start '{"ApplyOn": "PublishedVersions"}'
aws lambda publish-version --function-name my-java-handler
减少冷启动的提示:
- 使用
arm64架构(Graviton),以加快初始化并降低成本 - 尽量缩小部署包;大型依赖项使用层
- 在处理程序函数外初始化 SDK 客户端
- 除非确有需要,否则避免使用 VPC(VPC 冷启动时间更长)
- 对延迟敏感的路径使用预置并发
SAM 模板
# template.yaml - AWS SAM application
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: My serverless API
Globals:
Function:
Runtime: python3.12
Architectures: [arm64]
MemorySize: 256
Timeout: 30
Tracing: Active
Environment:
Variables:
STAGE: !Ref Stage
LOG_LEVEL: INFO
Parameters:
Stage:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]
Resources:
ApiFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub "${Stage}-api-handler"
Handler: app.handler
CodeUri: src/
Layers:
- !Ref DepsLayer
Events:
GetItems:
Type: Api
Properties:
Path: /items
Method: get
PostItem:
Type: Api
Properties:
Path: /items
Method: post
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref ItemsTable
QueueProcessor:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub "${Stage}-queue-processor"
Handler: sqs_processor.handler
CodeUri: src/
Events:
SQSEvent:
Type: SQS
Properties:
Queue: !GetAtt ProcessingQueue.Arn
BatchSize: 10
FunctionResponseTypes:
- ReportBatchItemFailures
DepsLayer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: common-deps
ContentUri: layer/
CompatibleRuntimes:
- python3.12
ItemsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Sub "${Stage}-items"
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProcessingQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub "${Stage}-processing"
VisibilityTimeout: 360
Outputs:
ApiEndpoint:
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod"
# SAM CLI commands
sam build
sam local invoke ApiFunction --event events/get-items.json
sam local start-api --port 3000
sam deploy --guided
sam logs --name ApiFunction --stack-name my-stack --tail
故障排除
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 函数超时 | 超时时间过短或下游响应缓慢 | 增加超时时间;检查 VPC/NAT 配置 |
| 内存不足 | 内存限制过低 | 增加 --memory-size;使用 CloudWatch Insights 分析性能 |
| 调用 AWS API 时权限被拒绝 | 执行角色缺少策略 | 为执行角色附加所需策略 |
| 冷启动时间超过 5s | 部署包过大或 VPC 开销过高 | 使用层、arm64 和预置并发;如果不需要 VPC,则移除 VPC |
| SQS 消息被重复处理 | 可见性超时短于函数超时时间 | 将队列可见性超时设为函数超时时间的 6 倍 |
| 事件源映射已禁用 | 连续错误过多 | 修复函数错误;重新启用映射 |
| 找不到层 | 区域错误或版本已删除 | 确认层 ARN 的区域与函数区域一致 |
| 金丝雀部署未切换流量 | 别名路由配置错误 | 确认路由配置中的版本号 |
| 无法调用函数 URL | 缺少基于资源的策略 | 添加 lambda:InvokeFunctionUrl 权限 |
相关技能
- aws-iam - 执行角色和权限
- terraform-aws - Lambda 的 IaC 部署
- aws-s3 - S3 事件触发器
- aws-vpc - Lambda 的 VPC 配置
- aws-cost-optimization - 优化 Lambda 支出
评论
支持 Markdown