LocalStack+Docker环境下S3 Bucket通知联动流程故障排查
问题场景与排查
我在Docker中用LocalStack(非专业版)搭建以下POC流程:
- 通过预签名URL将XML文件上传至S3桶
- 文件上传完成后,S3事件通知触发SQS队列
- SQS队列接收事件后触发Lambda函数
目前Bucket、SQS队列、Lambda函数均已成功创建,但上传文件至S3后无任何后续动作,流程完全卡住。
相关代码与配置
/bin/test.js
#!/usr/bin/env node const cdk = require('aws-cdk-lib'); const { TestStack } = require('../lib/test-stack'); const app = new cdk.App(); new TestStack(app, 'TestStack');
/lib/test-stack.js
const cdk = require("aws-cdk-lib"); const sqs = require("aws-cdk-lib/aws-sqs"); const s3 = require("aws-cdk-lib/aws-s3"); const lambda = require("aws-cdk-lib/aws-lambda"); const s3Notifications = require("aws-cdk-lib/aws-s3-notifications"); const { SqsEventSource } = require("aws-cdk-lib/aws-lambda-event-sources"); class TestStack extends cdk.Stack { constructor(scope, id, props) { super(scope, id, props); // S3 bucket const bucket = new s3.Bucket(this, "MyBucket", { removalPolicy: cdk.RemovalPolicy.DESTROY, }); // SQS queue const queue = new sqs.Queue(this, "MyQueue", { visibilityTimeout: cdk.Duration.seconds(300), }); // Lambda function const lambdaFunction = new lambda.Function(this, "MyLambdaFunction", { runtime: lambda.Runtime.NODEJS_18_X, handler: "lambda.handler", code: lambda.Code.fromAsset("lib/lambda"), environment: { QUEUE_URL: queue.queueUrl, }, }); // Set up S3 event notification to trigger SQS bucket.addEventNotification( s3.EventType.OBJECT_CREATED, new s3Notifications.SqsDestination(queue), ); // Set up SQS event source for Lambda function lambdaFunction.addEventSource(new SqsEventSource(queue)); } }
docker-compose.yml
version: "3.8" services: localstack: image: localstack/localstack:3.2.0 network_mode: bridge ports: - "4566:4566" - "4571:4571" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./localstack:/etc/localstack/init/ready.d
执行命令
docker-compose up -d cdklocal bootstrap cdklocal deploy
可能的问题与解决方法
1. S3向SQS发送消息的权限缺失
S3需要明确权限才能向SQS队列发送事件消息,默认CDK未配置该策略。修改/lib/test-stack.js,在创建queue后添加以下权限配置:
queue.addToResourcePolicy(new cdk.aws_iam.PolicyStatement({ actions: ['sqs:SendMessage'], resources: [queue.queueArn], principals: [new cdk.aws_iam.ServicePrincipal('s3.amazonaws.com')], conditions: { ArnLike: { 'aws:SourceArn': bucket.bucketArn } } }));
2. Lambda读取SQS的权限不足
虽然SqsEventSource通常会自动添加基础权限,但可手动补充确保权限完整,在创建lambdaFunction后添加:
lambdaFunction.addToRolePolicy(new cdk.aws_iam.PolicyStatement({ actions: ['sqs:ReceiveMessage', 'sqs:DeleteMessage', 'sqs:GetQueueAttributes'], resources: [queue.queueArn] }));
3. LocalStack服务仿真配置不全
在docker-compose.yml的localstack服务中添加环境变量,明确开启所需服务并启用调试日志:
services: localstack: # ... 原有配置 ... environment: - SERVICES=s3,sqs,lambda - DEBUG=1
4. 预签名URL生成与上传验证
- 用LocalStack CLI生成正确的预签名URL:
awslocal s3 presign s3://MyBucket/test.xml - 上传文件后验证是否存入S3:
awslocal s3 ls s3://MyBucket
5. 日志排查
查看LocalStack运行日志定位错误:
docker-compose logs localstack
检查SQS队列是否收到消息:
awslocal sqs receive-message --queue-url <你的队列URL>
查看Lambda执行日志:
awslocal logs describe-log-groups # 根据返回的日志组名称查看具体日志 awslocal logs get-log-events --log-group-name /aws/lambda/MyLambdaFunction --log-stream-name <日志流名称>
内容的提问来源于stack exchange,提问作者kato d
相关产品推荐
相关产品推荐

