AWS SQS队列无法接收SNS主题订阅消息问题排查
问题诊断与修复方案
1. SQS队列策略的安全传输条件完全反向
你的OutputQueuePolicy中,aws:SecureTransport被设为"false",这意味着仅允许非HTTPS(明文)请求发送消息到队列。但AWS SDK默认使用HTTPS发送请求,SNS向SQS推送消息也强制使用HTTPS,这个条件直接阻止了合法的HTTPS请求,导致消息无法投递。
修复:将aws:SecureTransport的值改为"true":
OutputQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Statement: - Effect: "Allow" Principal: "*" Action: - "sqs:SendMessage" Resource: Fn::GetAtt: [OutputQueue, Arn] Condition: ArnEquals: aws:SourceArn: !Ref OutputTopic Bool: aws:SecureTransport: "true" # 修正为true Queues: - Ref: OutputQueue
2. SNS主题策略逻辑完全错误
你的OutputTopicPolicy配置的是允许sqs.amazonaws.com向主题发布消息,这和实际需求完全不符:
- 你是通过AWS SDK向主题发布消息,需要的是允许你的IAM实体(如用户、角色)执行
sns:Publish - 策略中的
aws:SourceArn引用SQS队列ARN,逻辑混乱且无意义
如果你的IAM实体已具备向SNS主题发布的权限(比如通过IAM角色权限),可直接删除该错误的OutputTopicPolicy;若需在主题层面控制发布权限,示例配置如下:
OutputTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: PolicyDocument: Statement: - Sid: "Allow-IAM-Publish-To-Topic" Effect: "Allow" Principal: AWS: !Sub "arn:aws:iam::${AWS::AccountId}:user/YourPublishUser" # 替换为你的IAM实体ARN Action: "sns:Publish" Resource: !Ref OutputTopic Topics: - Ref: OutputTopic
3. SQS重驱允许策略配置反向
你的OutputQueue的RedriveAllowPolicy中,sourceQueueArns设置为死信队列的ARN,逻辑完全错误:
RedriveAllowPolicy用于指定哪些源队列可以将消息重驱到当前队列,主队列不需要接收其他队列的重驱消息- 若需允许死信队列将消息转回主队列,应在死信队列上配置该策略
修复主队列配置,移除错误的RedriveAllowPolicy:
OutputQueue: Type: AWS::SQS::Queue Properties: QueueName: isolation-change-output-queue RedrivePolicy: # 保留该配置,用于将失败消息转到死信队列 deadLetterTargetArn: Fn::GetAtt: [OutputDeadLetterQueue, Arn] maxReceiveCount: 5
如需支持死信队列转回主队列,可在死信队列添加配置:
OutputDeadLetterQueue: Type: AWS::SQS::Queue Properties: QueueName: isolation-change-output-dead-letter-queue RedriveAllowPolicy: redrivePermission: byQueue sourceQueueArns: - Fn::GetAtt: [OutputQueue, Arn]
4. 死信队列策略的资源范围过宽
你的OutputDeadLetterQueuePolicy中,Resource设为"*",会影响所有SQS队列,应限定为死信队列自身的ARN:
OutputDeadLetterQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Statement: - Effect: "Deny" Principal: "*" Action: - "sqs:SendMessage" - "sqs:ReceiveMessage" Resource: !GetAtt OutputDeadLetterQueue.Arn # 限定为死信队列ARN Condition: Bool: aws:SecureTransport: "true" # 建议改为true,禁止明文访问 Queues: - Ref: OutputDeadLetterQueue
验证步骤
- 应用修复后的CloudFormation模板
- 使用AWS SDK重新发布消息到SNS主题
- 查看SQS队列的消息计数,确认消息是否到达
- 若仍有问题,检查SNS主题的订阅状态是否为
Confirmed(CloudFormation会自动确认SQS订阅,也可在AWS控制台验证)
内容的提问来源于stack exchange,提问作者Michael Kitchell
相关产品推荐
相关产品推荐

