[rabbitmq-discuss] Help with persistence using RabbitMQ?

Marek Majkowski majek04 at gmail.com
Wed Apr 4 11:57:38 BST 2012

On Tue, Apr 3, 2012 at 17:22, iceblaze <iceblaze at gmail.com> wrote:
> Thanks for attempting to assist me here. I have made a light version of the
> module and a sender script as you requested. You can find the files here:
> http://iceblaze.com/rabbit.zip
> Simply unzip the files into the same directory and run the "sender.pl"
> script. Note that you will need to install Net::RabbitMQ from CPAN. You can
> also modify the login credentials for rabbit (right now its just using
> guest/guest) in $self of Rabbit.pm's new() function:
>         my $self =
>         {
>                 _rabbit => Net::RabbitMQ->new(),
>                 _rabbit_user => "guest",
>                 _rabbit_pass => "guest",
>                 _rabbit_host => "localhost",
>                 _rabbit_port => 5672,
>                 _queue => $queue,
>                 _channel => $channel,
>                 _no_ack => $no_ack,
>                 _queue_declared => '',
>         };

Oh, installing Net::RabbitMQ from CPAN wasn't easy at all!
But in the end after few attempts "cpan; notest install Net::RabbitMQ"
did the trick.

So, the problem is that in your code the "delivery_mode => 2"
doesn't work.

(btw, I debugged your issue by using the management plugin and
getting a message from the queue using it - it clearly shows
that "delivery_mode" is not set)

Reading the docs:

    publish($channel, $routing_key, $body, $options, $props)
    $props is an optional hash (the AMQP 'props') respecting the
following keys: { content_type => $string, content_encoding =>
$string, correlation_id => $string, reply_to => $string, expiration =>
$string, message_id => $string, type => $string, user_id => $string,
app_id => $string, delivery_mode => $integer, priority => $integer,
timestamp => $integer, }

So, "delivery_mode" is a feature of "props", not "options".
Appropriate code should therefore look like:

    $self->{_rabbit}->publish($self->{_channel}, $self->{_queue},
$data, {mandatory => 1, immediate => 0 }, {delivery_mode => 2});

Additionally, if you want to shield against broker falling down,
and have a reliable message delivery you should be using
transactions or publish confirms.

By default sending messages in rabbit is asynchronous. You don't know
when the message reached the broker and even if it did so.
Rabbit recognizes this and it doesn't immediately flush messages
to disk. Actually it will be quire reluctant to save them on disk
(this has been tweaked in RabbitMQ 2.8.0).

If you wish to make sure that Rabbit indeed handled messages
reliably, you must use transactions or publisher confirms to
get a confirmation of delivery from the broker.
Once the confirmation is received you can be sure the messages
are safe.

On the other hand if you are only going to be closing rabbit
gracefully (via the init scripts), setting the "delivery_mode"
properly should be enough to persist your messages.


More information about the rabbitmq-discuss mailing list