Rabbitmq retrieve multiple messages using single synchronous call

不羁岁月 提交于 2019-12-09 15:18:19

问题


Is there a way to receive multiple message using a single synchronous call ?

When I know that there are N messages( N could be a small value less than 10) in the queue, then I should be able to do something like channel.basic_get(String queue, boolean autoAck , int numberofMsg ). I don't want to make multiple requests to the server .


回答1:


RabbitMQ's basic.get doesn't support multiple messages unfortunately as seen in the docs. The preferred method to retrieve multiple messages is to use basic.consume which will push the messages to the client avoiding multiple round trips. acks are asynchronous so your client won't be waiting for the server to respond. basic.consume also has the benefit of allowing RabbitMQ to redeliver the message if the client disconnects, something that basic.get cannot do. This can be turned off as well setting no-ack to true.

Setting basic.qos prefetch-count will set the number of messages to push to the client at any time. If there isn't a message waiting on the client side (which would return immediately) client libraries tend to block with an optional timeout.




回答2:


You can use a QueueingConsumer implementation of Consumer interface which allows you to retrieve several messages in a single request.

 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:


First declare instance of QueueingBasicConsumer() wich wraps the model.
From the model execute model.BasicConsume(QueueName, false, consumer)
Then implement a loop that will loop around messages from the queue which will then processing
Next line - consumer.Queue.Dequeue() method - waiting for the message to be received from the queue.
Then convert byte array to a string and display it.
Model.BasicAck() - release message from the queue to receive next message
And then on the server side can start waiting for the next message to come through:

  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:


Not an elegant solution and does not solve making multiple calls but you can use the MessageCount method. For example:

  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");
      }


来源:https://stackoverflow.com/questions/17005515/rabbitmq-retrieve-multiple-messages-using-single-synchronous-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!