Rabbitmq retrieves multiple messages using a single synchronous call

Is there a way to get multiple messages using one synchronous call?

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

+10
source share
4 answers

RabbitMQ basic.get does not support multiple messages, unfortunately as seen from the documentation . The preferred method for receiving multiple messages is to use basic.consume , which will trigger messages to the client, avoiding multiple rounds. acks are asynchronous, so your client will not wait for a server response. basic.consume also has the advantage of allowing RabbitMQ to update the message, if the client disconnects, something basic.get cannot do. This can also be disabled by setting no-ack to true .

The basic.qos prefetch-count setting will set the number of messages that will click on the client at any time. If there is no pending message on the client side (which will be immediately returned), client libraries are usually blocked with an additional timeout.

+7
source

You can use the implementation of the Consumer interface in QueueingConsumer which allows you to receive multiple 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
source

First declare an instance of QueueingBasicConsumer () that completes the model.
From model execute model.BasicConsume (QueueName, false, consumer)
Then we implement a loop that will bypass messages from the queue, which then processes the next line - the consumer.Queue.Dequeue () method - waiting for the message to be received from the queue.
Then convert the byte array to a string and show it.
Model.BasicAck () - send a message from the queue to receive the next message
And then on the server side you can start to wait for the following message:

  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; } 
+1
source

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

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

Source: https://habr.com/ru/post/946873/


All Articles