[rabbitmq-discuss] Message ack timeout
Dmitriy Samovskiy
dmitriy.samovskiy at cohesiveft.com
Fri Oct 10 18:14:32 BST 2008
Hi Haldun,
Haldun Bayhantopcu wrote:
> Hi all,
>
> I'm trying to set up a system where one process produces several
> messages to many consumer processes. Each consumer creates a new
> record in database for each message. Since this is a bit slow,
> and heavy work for database when especially a lot of messages
> are produced in a short interval, I considered buffering the
> messages in consumer processes, and then sending them to the
Interesting problem. I personally can think of 2 ways how you can design it to meet your
requirements. (Please note it's purely on theoretical level, I haven't tested any of it).
1. Your consumer can establish a connection to rabbitmq broker, and then set up N
channels. Do basic.get on each channel, you will end up with a batch of at most N
messages, write the batch to the database, and then ack each message individually. Then
repeat.
A problem of course is that something may happen before you finish ack'ing all messages
(say after you ack'ed 2 of 5). It is my understanding that you won't be able to ack them
all together, since basic.ack can only ack messages on its channel. Not sure if you can
handle that in your app, but unack'ed 3 messages will be delivered to you again in this
scenario.
1a. You can use nearly identical approach by having your consumers open multiple
connections to broker (and a single channel inside each connection). Might get more
complicated, as you will have to juggle multiple sockets.
2. "buffering" is somewhat like "queueing", so why not use rabbitmq to be your buffer? In
this case, you set up a regular consumer (basic.consume). When a message arrives, you
publish it back to rabbitmq but to a different routing_key (say "finished.{batch_number}"
to topic-based exchange), and then ack the original one. Once you accumulate N messages,
you write entire batch to the database, and then send something like "END" to
"finished.{batch_number}". Have another process regularly check all finished.* messages,
and for those that were not properly END'ed, put them back into original queue.
In this case, your window of inconsistency should be much smaller I think. With multiple
consumer, make sure to use "finished.{consumer_id}_{batch_number}" instead.
- Dmitriy
More information about the rabbitmq-discuss
mailing list