Получить несколько сообщений из SQS - PullRequest
25 голосов
/ 01 апреля 2012

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

 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
 }

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

 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

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

Ответы [ 6 ]

32 голосов
/ 01 апреля 2012

Справочное руководство по API AWS: Query / QueryReceiveMessage

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

и

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

8 голосов
/ 14 сентября 2014

Полное объяснение этому (возможно, довольно своеобразному) поведению содержится в справочной документации SQS .

SQS хранит копии сообщений на нескольких серверах и на эти серверы поступают запросы на получение сообщений с одной из двух возможных стратегий ,

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

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

4 голосов
/ 31 августа 2013

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

2 голосов
/ 26 июля 2017

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

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

Снимок o / p:

Receiving messages from TestQueue.
Number of messages:10
Message
MessageId:     31a7c669-1f0c-4bf1-b18b-c7fa31f4e82d 
...
1 голос
/ 15 июня 2012

receiveMessageRequest.withMaxNumberOfMessages (10);

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

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

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

receiveMessageRequest.setMaxNumberOfMessages(10);

Как говорится, изменение этого не поможет исходной проблеме.

0 голосов
/ 13 марта 2019

Спасибо, Caoilte!

Я тоже столкнулся с этой проблемой.Окончательно решенный с помощью длинного опроса, следуйте конфигурации здесь: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-long-polling-for-queue.html

К сожалению, чтобы использовать длинный опрос, вы должны создать свою очередь как FIFO.Я попробовал стандартную очередь без удачи.

И при получении нужно также установить MaxNumberOfMessages.Поэтому мой код выглядит следующим образом:

ReceiveMessageRequest receive_request = new ReceiveMessageRequest () .withQueueUrl (QUEUE_URL) .withWaitTimeSeconds (20) .withMaxNumberOfMessages (10);

хотя все еще не решенAWS определенно должен предоставить более аккуратный API для такой основной операции приема.

С моей точки зрения, в AWS есть много интересных функций, но нет хороших API.Как эти парни все время спешат.

...