亚马逊 SQS 队列不存在。

4

我正在尝试使用Java SDK访问Amazon队列。该队列设置在具有EC2实例角色的环境中,因此我不需要使用凭据来访问它。 这是我的代码:

public AWSSimpleQueueServiceClient(String queueName, String endPoint) {
    try{
        this.queueName = queueName;
        logger.debug("Queue Name = " + this.queueName + "Endpoint = " + endPoint);
        this.sqs = new AmazonSQSClient(new InstanceProfileCredentialsProvider());
        if(endPoint != null) {
            this.sqs.setEndpoint(endPoint);
        }
    } catch (Exception e) {
        logger.error("Exception while creating AWS SQS Client = " + e.getMessage());
    }
}

QueueName和Endpoint从配置文件中获取。 我尝试从队列中发送/接收消息,但出现以下异常。

Exception in thread "main" com.amazonaws.services.sqs.model.QueueDoesNotExistException: The specified queue does not exist or you do not have access to it. (Service: AmazonSQS; Status Code: 400; Error Code: AWS.SimpleQueueService.NonExistentQueue; Request ID: c30b2c9a-0e62-560d-9306-628ebff676d8)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1160)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:748)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:467)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:302)
at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2422)
at com.amazonaws.services.sqs.AmazonSQSClient.getQueueUrl(AmazonSQSClient.java:541)
at com.ensighten.inform.sqsClient.AWSSimpleQueueServiceClient.getQueueUrl(AWSSimpleQueueServiceClient.java:66)

然而,当我尝试使用curl命令访问队列时,我会收到响应。
aws sqs receive-message --queue-url <Endpoint>/031143137427/<QueueName> --    region us-east-1
 {
    "Messages": [
        {
            "Body": "Test", 
            "ReceiptHandle":     "AQEBA49LjMDLPyyl4QKwHx9/oVFDV7mZDiOOpdKS/IC2zR3GNblg2IoHuqWBgr5iw7URCkL03Dm23TCs0Z2hB2DIzU+9qxZTOa9Ti57eiHOyAL2XAlbk7TAqGCR4lcsdSW8+LJ5zWCTkBUg5iZOqy4P0KFTfI7KtJJb2aAmeWJpApu+yJRTNAkYtdN91EcYOVFHqc1p6HJmtvvW6vJwfHB5JEbagXdfWwH3/UnJ/O36JwuFoLDp/NBRu6TO+bmYxeZmCN4GdhHuT0a11weki6Ez47Ln63G11LeQ4SFdZTC7QOWflypf8FSbG8W4JGGPZ8J8iWTkW7PGGw6DRavSu97rx3w==", 
            "MD5OfBody": "1f871ceacd9f4028ed371e91400efe80", 
            "MessageId": "0f6290d2-4554-4d96-8f93-7564ef667feb"
        }
    ]
}

当我在另一台设置了EC2角色的机器上尝试时,我遇到了这个异常。

Exception in thread "main" com.amazonaws.AmazonClientException: Unable to load credentials from Amazon EC2 metadata service
at com.amazonaws.auth.InstanceProfileCredentialsProvider.handleError(InstanceProfileCredentialsProvider.java:244)
at com.amazonaws.auth.InstanceProfileCredentialsProvider.loadCredentials(InstanceProfileCredentialsProvider.java:225)
at com.amazonaws.auth.InstanceProfileCredentialsProvider.getCredentials(InstanceProfileCredentialsProvider.java:124)
at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2413)
at com.amazonaws.services.sqs.AmazonSQSClient.getQueueUrl(AmazonSQSClient.java:541)
at com.ensighten.inform.sqsClient.AWSSimpleQueueServiceClient.getQueueUrl(AWSSimpleQueueServiceClient.java:74)
at com.ensighten.inform.sqsClient.AWSSimpleQueueServiceClient.getMessagesFromQueue(AWSSimpleQueueServiceClient.java:93)
at com.ensighten.inform.jobRunner.TestJobRunner.execute(TestJobRunner.java:96)
at com.ensighten.inform.jobRunner.TestJobRunner.main(TestJobRunner.java:90)
Caused by: java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at   java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:432)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:527)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:211)
at sun.net.www.http.HttpClient.New(HttpClient.java:308)
at sun.net.www.http.HttpClient.New(HttpClient.java:326)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:996)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:932)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:850)
at com.amazonaws.internal.EC2MetadataClient.readResource(EC2MetadataClient.java:90)
at com.amazonaws.internal.EC2MetadataClient.getDefaultCredentials(EC2MetadataClient.java:55)
at com.amazonaws.auth.InstanceProfileCredentialsProvider.loadCredentials(InstanceProfileCredentialsProvider.java:186)
... 7 more

以下是获取队列URL的两种方式。但是以上异常错误。

public String getQueueUrl() {
    GetQueueUrlRequest queueUrlRequest = new GetQueueUrlRequest(this.queueName);
    logger.debug("Queue Name... = " + this.queueName);
    //FIRST WAY -----------> EXCEPTION on the line below
    System.out.println("Queue URL .....= " + this.sqs.getQueueUrl(this.queueName));
    //SECOND WAY
    return this.sqs.getQueueUrl(queueUrlRequest).getQueueUrl();
}

我一直在尝试解决这个问题。如果有帮助,将不胜感激。


你是否将终点传递给你的方法,以便进行设置?这是必需的。 - mjuopperi
是的,构造函数为sqs对象设置了终端点。 - Programmer
12
你的实例角色是否有调用 GetQueueUrl 的权限?当你通过手动构建 QueueUrl 参数来使用 CLI 时,你将绕过该调用。 - David Murray
1
@DavidMurray 这是一个很好的观点。我不知道调用getQueueUrl()是否需要权限。我可能需要检查一下。它们需要与队列权限相同吗?或者它是如何工作的? - Programmer
权限已添加以访问getQueueUrl()。我已编辑我的问题,展示了我如何调用该方法以及出错的位置。 - Programmer
2
@DavidMurray +1 你的建议解决了我的问题。值得作为一个答案。 - Mattiavelli
1个回答

1
如评论中David Murray所指出的,如果SQS队列存在,则可能是权限问题。请确保EC2实例角色被允许使用sqs:GetQueueUrl操作。
以下是包含必要声明的示例策略:
{
   "Version": "2012-10-17",
   "Statement": [{
      "Effect": "Allow",
      "Action": "sqs:GetQueueUrl",
      "Resource": "QUEUE_ARN"
   }]
}

请确保将QUEUE_ARN替换为SQS队列ARN。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接