Asynchronous acknowledgments in RabbitMQ (and node.js)
I have a specific use case of RabbitMQ in mind, and I'd like to clarify certain things and ask for recommendations.
Consider this scenario:
1- I publish two messages, that are tasks to be executed: messageA and then messageB
2- my consumer gets messageA, executes the task contained in this message, but while the task is running, the server crashes
My question is: when the server is restarted, will messageA be requeued, and will it be requeued before messageB (same order than before the crash)?
开发者_如何学PythonFor what I understand, messageA would be lost if the server was to crash, because my consumer has acknowledged it by default, upon reception of the message.
So my idea is to consume and acknowledge message separately: consume first, run the task, and then acknowledge the message when the task has been executed successfully.
Do you see a problem with this approach? Would you advise me to do anything else?
RabbitMQ does not keep the order of messages for requeue:
For the most part, yes. Say a publisher publishes messages M1, M2, M3 and M4 (in that order) on the same channel and with the same routing information. If these messages are routed to a queue then they will end up in the same order that they were published. Consuming on the queue will yield M1, M2, M3 and then M4.
However, the order is only guaranteed in the absence of requeuing. A message will be implicitly requeued if a consumer closes the channel before ack'ing a message. For example, if a consumer receives M1, fails to ack and closes the channel then the next consumer will receive messages in the order M2, M3, M4, M1. Messages can also be explicitly requeued if the consumer calls basic.recover{requeue=true}. The FAQ on at least once delivery talks about this in some more detail.
RabbitMQ FAQ
This can be done but RabbitMQ doesn't do it automatically you need to manage the lifecycle yourself by wrapping the children messages in a parent message. You would then have code that manages the parent message and handling rolling back if message 1 succeeds but message 2 fails. Hopefully that helps..
best regards
Messages that are consumed in no-ack mode (see http://www.rabbitmq.com/amqp-0-9-1-reference.html#domain.no-ack) will not be requeued after a server crash, because the server has completely forgotten about such messages when they get delivered. The consumer takes responsibility for such messages after delivery.
Acknowledging the message only after successfully completing the task is the correct approach in your scenario. If you want messages to survive a broker crash then you must also make sure that the queue is durable and that the messages are published persistent (delivery-mode 2) and that publisher-confirms or transactions are used to ensure that messages are written to disk.
If the broker crashes while messageA is being processed then message order will be preserved. If the consumer instead of the broker were to crash then the message order will be reversed.
精彩评论