Rabbitmq извлекает несколько сообщений, используя один синхронный вызов

Есть ли способ получить несколько сообщений, используя один синхронный вызов?

Когда я знаю, что в очереди есть N сообщений (N может быть маленьким значением менее 10), я должен иметь возможность делать что-то вроде channel.basic_get (String queue, boolean autoAck, int numberofMsg). Я не хочу делать несколько запросов на сервер.

Ответ 1

RabbitMQ basic.get не поддерживает несколько сообщений, к сожалению как видно из документации. Предпочтительным методом получения нескольких сообщений является использование basic.consume, который будет вызывать сообщения клиенту, избегая нескольких раундов. acks являются асинхронными, поэтому ваш клиент не будет ждать ответа сервера. basic.consume также имеет преимущество, позволяя RabbitMQ обновлять сообщение, если клиент отключается, то, что basic.get не может сделать. Это также можно отключить, установив no-ack в true.

Настройка basic.qos prefetch-count будет устанавливать количество сообщений, которые будут нажимать на клиента в любое время. Если на стороне клиента нет ожидающего сообщения (которое сразу будет возвращено), библиотеки клиентов, как правило, блокируются с дополнительным таймаутом.

Ответ 2

Вы можете использовать реализацию интерфейса Consumer в QueueingConsumer которая позволяет получать несколько сообщений за один запрос.

 QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
 channel.basicConsume(plugin.getQueueName(), false, queueingConsumer);

 for(int i = 0; i < 10; i++){
    QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery(100);//read timeout in ms
    if(delivery == null){
      break;
    }
 }

Ответ 3

Сначала объявите экземпляр QueueingBasicConsumer(), который завершает модель.
Из модели execute model.BasicConsume(QueueName, false, consumer)
Затем реализуем цикл, который будет обходить сообщения из очереди, которая затем обрабатывает Следующая строка - метод consumer.Queue.Dequeue() - ожидание получения сообщения из очереди.
Затем преобразуйте массив байтов в строку и покажите его.
Model.BasicAck() - отправить сообщение из очереди для получения следующего сообщения
И затем на стороне сервера можно начать ждать следующего сообщения:

  public string GetMessagesByQueue(string QueueName)
    {
        var consumer = new QueueingBasicConsumer(_model);
        _model.BasicConsume(QueueName, false, consumer);

        string message = string.Empty;

        while (Enabled)
        {
            //Get next message
            var deliveryArgs = (BasicDeliverEventArgs)consumer.Queue.Dequeue();

            //Serialize message
             message = Encoding.Default.GetString(deliveryArgs.Body);
                _model.BasicAck(deliveryArgs.DeliveryTag, false);
        }
        return message;
    }

Ответ 4

Не элегантное решение и не решает многократные вызовы, но вы можете использовать метод MessageCount. Например:

  bool noAck = false;
  var messageCount = channel.MessageCount("hello");
  BasicGetResult result = null;
  if (messageCount == 0)
  {
      // No messages available
  }
  else
  {
      while (messageCount > 0)
      {
          result = channel.BasicGet("hello", noAck);
          var message = Encoding.UTF8.GetString(result.Body);
          //process message .....
          messageCount = channel.MessageCount("hello");
      }