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

调用publishMessage()后SNS无法向SQS推送消息,求助排查原因

SNS无法推送消息到动态创建的SQS队列的排查问题

我通过publishMessage()方法可动态创建SNS Topic、订阅动态SQS队列,但SNS无法将消息推送到SQS队列,请问可能存在哪些问题?

相关实现代码如下:

public void publishMessage(String topicName, String message) {
        String topicArn = createTopic(topicName);
        subSQS(topicArn, topicName);
        pubTopic(message, topicArn);
    }

    private String createTopic(String topicName) {
        CreateTopicResponse result = null;
        CreateTopicRequest request = CreateTopicRequest.builder()
                .name(topicName)
                .build();

        result = snsClient.createTopic(request);
        return result.topicArn();
    }

    private void pubTopic(String message, String topicArn) {

        PublishRequest request = PublishRequest.builder()
                .message(message)
                .topicArn(topicArn)
                .build();

        PublishResponse result = this.snsClient.publish(request);
        log.info(result.messageId() + " Message sent. Status is " + result.sdkHttpResponse().statusCode());
    }

    private void subSQS(String topicArn, String queueName) {
        
        CreateQueueRequest createQueueRequest = CreateQueueRequest.builder().queueName(queueName).build();
        String queueUrl = sqsClient.createQueue(createQueueRequest).queueUrl();

        // Get the ARN of the SQS queue
        GetQueueAttributesRequest getQueueAttributesRequest = GetQueueAttributesRequest.builder()
                .queueUrl(queueUrl)
                .attributeNames( QueueAttributeName.QUEUE_ARN)
                .build();
        GetQueueAttributesResponse queueAttributes = sqsClient.getQueueAttributes(getQueueAttributesRequest);
        String queueArn = queueAttributes.attributes().get(QueueAttributeName.QUEUE_ARN);
        
        try {
            SubscribeRequest request = SubscribeRequest.builder()
                    .protocol("sqs")
                    .endpoint(queueArn)
                    .returnSubscriptionArn(true)
                    .topicArn(topicArn)
                    .build();

            SubscribeResponse result = snsClient.subscribe(request);
            System.out.println("Subscription ARN: " + result.subscriptionArn() + "\n\n Status is " + result.sdkHttpResponse().statusCode());
        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }

可能的问题点

  • SQS队列权限不足:SNS没有被授权向目标SQS队列发送消息。动态创建队列时,需要附加允许对应SNS Topic执行sqs:SendMessage操作的访问政策。示例政策如下:
    {
      "Version": "2008-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {"Service": "sns.amazonaws.com"},
          "Action": "sqs:SendMessage",
          "Resource": "你的队列ARN",
          "Condition": {
            "ArnEquals": {"aws:SourceArn": "你的SNS Topic ARN"}
          }
        }
      ]
    }
    
  • 跨区域部署问题:检查SNS客户端与SQS客户端是否配置了相同的AWS区域。如果Topic和队列不在同一区域,SNS无法完成消息投递。
  • 订阅生效延迟:代码中在订阅创建完成后立即发布消息,而SNS订阅可能存在短暂的生效延迟,导致消息无法被路由到队列。可以添加几秒延时后再发布,或者通过API确认订阅状态。
  • 队列ARN获取错误:检查QueueAttributeName.QUEUE_ARN的解析是否正确,确保获取到的队列ARN格式正确,没有拼写或格式错误。
  • IAM角色权限缺失:执行代码的IAM角色需要同时具备以下权限:sns:CreateTopic、sns:Subscribe、sqs:CreateQueue、sqs:GetQueueAttributes,权限不足会导致流程隐性失败。
  • 消息过滤策略限制:如果目标SNS Topic设置了消息过滤策略,而发布的消息不符合过滤条件,会被SNS拦截,无法投递到队列。
  • 消息大小超限:SQS队列默认允许的最大消息大小为256KB,如果发布的消息超过该限制,会导致投递失败。

内容的提问来源于stack exchange,提问作者Sathiamoorthy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 01:00:14