调用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
相关产品推荐
相关产品推荐

