You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:41:06