Подтвердить что ты не робот

Извлечение нескольких сообщений из SQS

У меня есть несколько сообщений в 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
 }

Я также пробовал использовать 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

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

4b9b3361

Ответ 1

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

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

и

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

receiveMessageRequest.withMaxNumberOfMessages(10);

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

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

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

receiveMessageRequest.setMaxNumberOfMessages(10);

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

Ответ 5

Я просто пытался сделать то же самое и с помощью этих двух атрибутов 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 
...