[rabbitmq-discuss] Sequential message processing guarantee

Alexandru Scvorţov alexandru at rabbitmq.com
Mon Jan 23 15:22:13 GMT 2012


> Is my understanding correct?

Almost.  Deliveries will happen serially on a channel, so, as long as you
only have one consumer, everything should be fine.

On Mon, Jan 23, 2012 at 06:54:15AM -0800, Yogesh Ketkar wrote:
> Hello Alex,
> 
> I thought, using default Connection con = factory.newConnection(),
> ThreadPool which gets created will have more than one thread and
> calling basicConsume will result in processing of messages on multiple
> threads.
> 
> But if we explicitly provide Executors.newSingleThreadExecutor() to
> newConnection method, only single thread will come into play with
> basicConsume.
> 
> Is my understanding correct?
> 
> regards, Yogesh
> 
> 
> On Jan 23, 7:48 pm, Alexandru Scvorţov <alexan... at rabbitmq.com> wrote:
> > Hi Yogesh,
> >
> > > using channel.basicConsume on the channel which is created like this
> > > ExecutorService es = Executors.newSingleThreadExecutor();
> > > Connection connection = factory.newConnection(es);
> > > final Channel channel = connection.createChannel();
> >
> > > is probably a better approach.
> > > Any comments on this?
> >
> > I don't quite see the point of the ExecutorService.
> >
> > Just doing this:
> >
> > > Connection connection = factory.newConnection(es);
> > > final Channel channel = connection.createChannel();
> >
> > Then, calling basicConsume with your own subclass of DefaultConsumer
> > should be fine.
> >
> > Cheers,
> > Alex
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > On Mon, Jan 23, 2012 at 08:08:37PM +0530, Yogesh Ketkar wrote:
> > > Thanks Alex.
> >
> > > I think, for sequential message processing, rather than this pattern
> > > while(true) {
> > >     GetResponse res = channel.basicGet(QUEUE_NAME, false);
> > >     if(res != null) {
> > >         // process and ack message
> > >    }
> > > }
> >
> > > using channel.basicConsume on the channel which is created like this
> > > ExecutorService es = Executors.newSingleThreadExecutor();
> > > Connection connection = factory.newConnection(es);
> > > final Channel channel = connection.createChannel();
> >
> > > is probably a better approach.
> > > Any comments on this?
> >
> > > regards, Yogesh
> >
> > > 2012/1/23 Alexandru Scvorţov <alexan... at rabbitmq.com>
> >
> > > > Hi Yogesh,
> >
> > > > In the absence of consumer failures, RabbitMQ will deliver messages from
> > > > a queue in order.
> >
> > > > So, if messages 1, 2, 3 reach a queue in order, RabbitMQ will deliver
> > > > them to consumers in the same order (1, 2, 3).
> >
> > > > But, if consumers fail before acknowledging the messages (or if they
> > > > reject the messages), those messages will requeued at the end of the
> > > > queue.  So, if the consumer that got message 1 rejects it, the new
> > > > order of messages will be 2, 3, 1.
> >
> > > > This all deals with message *delivery*.
> >
> > > > > There are multiple consumer threads consuming the messages.
> > > > > Though multiple threads are consuming the messages, I observed that
> > > > > messages still get processed sequentially.
> > > > > Is that the case and if NOT, what is the way to guarantee sequential
> > > > > processing of messages on one queue?
> >
> > > > The library makes no guarantees about the order in which you process
> > > > messages, only about the order in which they're delivered.
> >
> > > > If you want to process all the messages on a queue in order, only
> > > > consume from one thread (doing basic.get from one thread like you
> > > > suggested in the other email would work, but would also be highly
> > > > inefficient).
> >
> > > > Does this answer your question?
> >
> > > > Cheers,
> > > > Alex
> >
> > > > On Sun, Jan 22, 2012 at 09:38:40AM -0800, Yogesh Ketkar wrote:
> > > > > Running the code below, gives
> > > > > channel.basicConsume(QUEUE_NAME, autoAck, CONSUMER_TAG,
> > > > >       new DefaultConsumer(channel)  {
> > > > >         @Override
> > > > >         public void handleDelivery(String consumerTag, Envelope
> > > > > envelope, BasicProperties properties, byte[] body) {
> > > > >                 System.out.println(Thread.currentThread().getName());
> > > > >          }
> > > > > }
> >
> > > > > o/p like
> > > > > pool-1-thread-1
> > > > > pool-1-thread-2
> > > > > pool-1-thread-3
> > > > > etc
> >
> > > > > There are multiple consumer threads consuming the messages.
> > > > > Though multiple threads are consuming the messages, I observed that
> > > > > messages still get processed sequentially.
> > > > > Is that the case and if NOT, what is the way to guarantee sequential
> > > > > processing of messages on one queue?
> >
> > > > > regards, Yogesh
> >
> > > > > _______________________________________________
> > > > > rabbitmq-discuss mailing list
> > > > > rabbitmq-disc... at lists.rabbitmq.com
> > > > >https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
> >
> > _______________________________________________
> > rabbitmq-discuss mailing list
> > rabbitmq-disc... at lists.rabbitmq.comhttps://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
> _______________________________________________
> 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