2012-03-31 4 views
20

У меня есть несколько сообщений в SQS. Следующий код всегда возвращает только один, даже если есть десятки видимых (не в полете). setMaxNumberOfMessages Я думал, что позволит несколько раз потреблять сразу. Неужели я это неправильно понял?Извлечение нескольких сообщений из SQS

CreateQueueRequest createQueueRequest = new CreateQueueRequest().withQueueName(queueName); 
String queueUrl = sqs.createQueue(createQueueRequest).getQueueUrl(); 
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueUrl); 
receiveMessageRequest.setMaxNumberOfMessages(10); 
List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages(); 
for (Message message : messages) { 
     // i'm a message from SQS 
} 

Я также попытался использовать withMaxNumberOfMessages без такой удачи:

receiveMessageRequest.withMaxNumberOfMessages(10); 

Как я знаю, что есть сообщения в очереди? Более 1?

Set<String> attrs = new HashSet<String>(); 
attrs.add("ApproximateNumberOfMessages"); 
CreateQueueRequest createQueueRequest = new CreateQueueRequest().withQueueName(queueName); 
GetQueueAttributesRequest a = new GetQueueAttributesRequest().withQueueUrl(sqs.createQueue(createQueueRequest).getQueueUrl()).withAttributeNames(attrs); 
Map<String,String> result = sqs.getQueueAttributes(a).getAttributes(); 
int num = Integer.parseInt(result.get("ApproximateNumberOfMessages")); 

выше всегда выполняется до и дает мне int, что> 1

Спасибо за ваш вклад

ответ

27

AWS API Reference Guide: Query/QueryReceiveMessage

Благодаря распределенной природе очереди, взвешенный случайный набор машин отбирается на вызов ReceiveMessage. Это означает, что возвращаются только сообщения на дискретизированных машинах. Если количество сообщений в очереди невелико (менее 1000), вероятно, вы получите меньше сообщений, чем вы запросили на звонок ReceiveMessage. Если количество сообщений в очереди крайне невелико, вы не можете получать сообщения в определенном ответе ReceiveMessage; в этом случае вам следует повторить запрос.

и

MaxNumberOfMessages: Максимальное количество сообщений, чтобы вернуться. SQS никогда не возвращает больше сообщений, чем это значение, но может вернуть меньше.

+1

Ваша ссылка ссылка не работает сейчас, не могли бы вы обновить его? Я думаю, это http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sqs/AmazonSQSClient.html#receiveMessage(java.lang.String) – coderz

1

receiveMessageRequest.withMaxNumberOfMessages (10);

Просто чтобы быть ясно, тем более практическое применение этого было бы добавить в свой конструктор, как это:

ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueUrl).withMaxNumberOfMessages(10); 

В противном случае, вы можете также просто сделать:

receiveMessageRequest.setMaxNumberOfMessages(10); 

При этом изменение этого не поможет исходной проблеме.

4

У меня была та же проблема. Какое у вас время ожидания получения сообщения для вашей очереди? Когда мой был в 0, он возвращал только 1 сообщение, даже если в очереди было 8. Когда я увеличил время ожидания получения сообщения, я получил все из них. Кажется, для меня это багги.

6

Существует подробное объяснение этого (возможно, весьма своеобразного) поведения в SQS reference documentation.

SQS stores copies of messages on multiple servers и получать запросы на сообщение сделаны эти серверы с одним из two possible strategies,

  • Краткое Опрос: Поведение по умолчанию, только подмножество серверов (на основе взвешенного случайного распределения) являются запросил.
  • Длительный опрос: разрешено путем установки атрибута WaitTimeSeconds на ненулевое значение, запрашиваются все серверы.

На практике для моих ограниченных тестов я всегда получаю одно сообщение с коротким опросом, как и вы.

0

Я просто пробовал то же самое и с помощью этих двух атрибутов setMaxNumberOfMessages и setWaitTimeSeconds я смог получить 10 сообщений.

ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(myQueueUrl); 
         receiveMessageRequest.setMaxNumberOfMessages(10); 
         receiveMessageRequest.setWaitTimeSeconds(20); 

Снимок о/р:

Receiving messages from TestQueue. 
Number of messages:10 
Message 
MessageId:  31a7c669-1f0c-4bf1-b18b-c7fa31f4e82d 
...