We have a durable RabbitMQ queue. When consumer gets item from the queue, it processes it and then acknowledges it. If consumer fails to process the item it prints an error expecting someone to fix the problem an开发者_开发问答d stops. No acknowledgement is being sent. When consumer restarts the item it receives is next item in the queue, not the item without ack. Basic.Recover() doesn't help (using .NET client). Any ideas how to make it work as a queue - always get the first item if it is not acked.
Messages can be consumed in two ways noAck=false or noAck=true
noAck is a parameter on both Model.BasicConsume and Model.BasicGet
When noAck is set to true messages are automatically removed from the queue after being delivered. If noAsk is set to false messages are only removed when you call basicAck.
If noAck=false and you do not call basicAck the message will remain but you will not receive in on other consumers until you restart the application (or close the connection that consumed it first). If you call BasicReject the message will be redelivered to a subscriber.
I hope this helps.
See this entry in the RabbitMQ FAQ. While you may want RabbitMQ to re-queue your unacked messages right back to the head of the queue (where they were before your consumer pulled them down), the reality is likely going to be different, as you've experienced.
So it's not that Basic.Recover()
doesn't work (the message was placed back on the queue for future reprocessing) just that it doesn't work the way you expected.
Something in the back of my mind tells me that you may be able to get the behavior you want by setting a prefetch count of 1 and having at most only one consumer connect to the queue at any time, but I can't guarantee that's the case. It's worth trying. However even if it works it's not something to rely on staying the case forever, and with such a low prefetch count your consumer's messages/second performance will probably suffer.
RabbitMQ seems to have fixed part of this issue since 2.7.0, as now messages will be requeued in publication order. Although if you have more than one subscriber to a queue, you may still have message arriving out of the original order.
You can get this behaviour by having a pair of queues, one high priority and one normal priority. Set the prefetch count to 1, and then alternate between the queues using basic.get. Most of the time the priority queue will be empty, but when you want to requeue, publish the message again onto the high priority queue instead.
This works in a scenario where you have multiple processes consuming the message stream, and one process decides to bail out on a message. That message will be picked up almost immediately by another process.
精彩评论