Amazon SQS队列不存在

时间:2015-07-06 17:38:00

标签: java amazon-sqs aws-java-sdk

我正在尝试使用java sdk访问亚马逊队列。队列设置在具有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();
}

我一直试图解决这个问题。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:-1)

当您尝试访问不再存在的SQS队列或者您没有访问它的权限时,会发生类似的问题。

正如您在问题中提到的那样,当通过AWS CLI发出curl命令时,SQS队列可以正常工作。这是一种很好的调试方法,可以确定它是否可以通过CLI在本地运行。

下一步是检查您的EC2实例是否具有所需的必要权限。根据AWS的建议,切勿在EC2实例中使用凭证或密钥秘密值来访问AWS中的其他资源。最好的方法是使用 IAM角色。根据您的问题,您需要向您的特定角色授予权限,才能访问AWS SQS资源。然后,AWS将允许在EC2实例上运行的应用程序从SQS获取消息。

documentation提供了有关可以分配给角色的必要权限的详细信息。