[rabbitmq-discuss] Message redelivering doubt with one and with more than one consumers.

Alfonso Pantoja alfonso.pantoja at gmail.com
Mon Feb 14 22:24:14 GMT 2011


Hi Alex,

Thank for that clear explanation. You really helped me.

In the first approach of my code I didn't ack messages that couldn't
be processed by my business logic (for instance when they couldn't be
stored in the database due to a connection error) so I counted then
un-ack'd messages and when they reach a threshold number I called
basic.recover because as I read on the documentation basic.reject was
not implemented in 1.7.2.
Now using 2.2.0 version (server and API) I replaced basic.recover with
basic.reject which doesn't requeue the whole messages in the queue as
basic.recover did (and the CPU wasn't very 'happy' with it)

The use of basic.reject{requeue=true} implies that there is no need to
un-ack messages thus counting those messages and calling basic.recover
to put them again in the queue is not necessary.
So when receiving messages the only possible actions are basic.ack for
messages OK, basic.reject{requeue=true}  for messages that couldn't be
processed and basic.reject{requeue=false} for discarding the messages
we don't want to process.
In this scenario I think that un-ack'd messages are only possible when
the consumer crashes or it is stopped so basic.recover calls are
totally unnecessary because, as you said, the messages will be requeue
when a consumer is connected again.
An also I suppose it is better to actively response to Rabbit about
the messages (discarding  or requeing using basic.reject) instead of
"not respoding" for un-ack them.

Am I right or am I missing something?


Best regards,


Alfonso










2011/2/14 Alexandru Scvorţov <alexandru at rabbitmq.com>:
> Hi,
>
>> In a scenario with one consumer as I saw in my tests, the consumer
>> received messages with the Redelivered=true AMQP header atribute.
>> The consumer was based in the classes provided by the .NET API and as
>> I remember the consumer-tag is random generated by the server.
>
> Sounds good.
>
>> When there is a only one consumer (with a random consumer-tag name)
>> and a message is not acked when the consumer is reconnected (so has
>> another random tag name) that message is redelivered?
>
> Yes, un-ack'd messages will be redelivered to the consumer when it
> reconnects.  Be aware, though, they will be redelivered *after* the
> messages still on the queue (i.e. the undelivered ones) are delivered.
>
> So, if the following messages are published to the queue:
>  1 2 3 4 5 6
>
> And the following are delivered but not ack'd by the consumer:
>  1 2 3
>
> If the consumer crashes and reconnects, the messages delivered in order
> will be:
>  4 5 6 1 2 3
>
>> Based on my experience I think this is true but don't understand that
>> "If that same consumer then reconnects and creates a new subscription
>> to the same queue"...
>
> That's just another way of saying it reconnects and starts consuming
> again.
>
>> By the was my consumer always tries to create the queue and the
>> bindings every time it connects to RabbitMQ.
>
> That's perfect.  You should always do that.
>
>> And also I'm wondering how this behavior acts when there are more than
>> one consumer (same queue and same bindings)...
>
> Messages are delivered one at a time to consumers in round-robin order.
> If a message is delivered and the consumer dies, the message is
> republished to the queue and a consumer will eventually get it (note
> that it may be the same client if it reconnects).
>
>> Under what circumstances an unack message wouldn't be redelivered again?
>
> In none of the circumstances we were talking about.  A client can
> basic.reject{requeue=false} a message, in which case it will not be
> requeued.
>
> Hope this helps.
>
> Cheers,
> Alex
>
> On Thu, Feb 10, 2011 at 10:26:53AM +0100, Alfonso Pantoja wrote:
>> Hi,
>>
>> on the RabbitMQ FAQ page I see the response to
>>
>> "Can you explain the cases where a message might be delivered to a
>> consumer more than once?"
>> the following:
>>
>> "If a message is delivered to a consumer, and that consumer then dies
>> (or closes the channel which has the subscription to the queue, or
>> closes the connection itself) without acking the message, then
>> RabbitMQ will reinject the message into the queue. If that same
>> consumer then reconnects and creates a new subscription to the same
>> queue, it's possible it'll receive the same message again. This is 'at
>> least once' delivery and is very deliberate design to ensure that
>> messages are not lost in transit."
>>
>>
>> So my doubt is:
>>
>> In a scenario with one consumer as I saw in my tests, the consumer
>> received messages with the Redelivered=true AMQP header atribute.
>> The consumer was based in the classes provided by the .NET API and as
>> I remember the consumer-tag is random generated by the server.
>>
>> When there is a only one consumer (with a random consumer-tag name)
>> and a message is not acked when the consumer is reconnected (so has
>> another random tag name) that message is redelivered?
>> Based on my experience I think this is true but don't understand that
>> "If that same consumer then reconnects and creates a new subscription
>> to the same queue"...
>> By the was my consumer always tries to create the queue and the
>> bindings every time it connects to RabbitMQ.
>>
>> And also I'm wondering how this behavior acts when there are more than
>> one consumer (same queue and same bindings)...
>>
>> Under what circumstances an unack message wouldn't be redelivered again?
>>
>> Thank you in advance.
>>
>> Regards,
>>
>> Alfonso
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> The consumer can also call basic.recover which tells rabbit to resend
>> all the messages sent to the consumer for which rabbit has not
>> received an ack for. This basically amounts to the consumer saying "I
>> know you sent me some messages, but I've forgotten what they are.
>> Could you resend them all again?".
>> _______________________________________________
>> rabbitmq-discuss mailing list
>> rabbitmq-discuss at lists.rabbitmq.com
>> https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
>


More information about the rabbitmq-discuss mailing list