Ruby AMQP persistent message is deleted after restarting RabbitMQ
I have a ruby script that creates a message using AMQP in RabbitMQ.
# above code sets up config for connecting to Rabb开发者_StackOverflow中文版itMQ via APMQ
AMQP.start(:host => 'localhost') do
amq = MQ.new
amq.queue('initiate', :durable => true).publish(message_id, :persistent => true)
AMQP.stop{ EM.stop }
end
If the RabbitMQ server is restarted, the message is no longer in the initiate queue (or any queue, for that matter). What am I doing wrong that the message is not persistent? I've also tried explicitly creating a durable exchange, and binding the queue to that exchange, but the message is still deleted after RabbitMQ restart.
As already mentioned, if you just mark messages as persistent they will not necessarily get persisted straight away, so if the server shuts down unexpectedly they may never end up on disk.
So what do you do if you really need the message to be on disk, even if the server crashes?
There are two things you can do. One is to wrap your publish in a transaction. When you have committed the transaction, the message will be on disk (if it's not already delivered to a consumer of course). However, this adds a synchronous call to the server, so it can slow you down. If you know you're going to publish a lot of messages, you can wrap a bunch of publishes in a transaction, then when you commit you know they're all on disk.
The other (higher performance) alternative is to use publish confirms. But these are new in the 2.3.1 server and I don't think any Ruby clients support them yet.
Finally, RabbitMQ will anyway periodically flush persistent messages to disk even in the absence of confirms, transactions and controlled shutdowns. However there's a bug in 2.2.0 which means that this sometimes doesn't happen for a long time, so upgrading to 2.3.1 might be worthwhile.
Funny I was just Googling for the same problem. RabbitMQ 2.2.0, default options. In my case, Ruby clients using rubygem-amqp-0.6.7-3.el5 from EPEL. Durable queues bound to Durable fanout exchange, publishing messages with :persistent => true. Messages lost on server restart. -Alan
Yes, Simon is right. About publisher confirms (described at http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms), I plan to support them in AMQP 0.8 which shall be released soon.
BTW, in the original example, the first argument for publish is supposed to be the actual data, everything else is specified via options, so it's publish(message, opts) rather than publish(message_id, opts).
精彩评论