[rabbitmq-discuss] How to shutdown cleanly a Java application using Consumers?

Gary Russell grussell at gopivotal.com
Wed Apr 2 21:50:56 BST 2014


Internally, in essence, the listener container tells each consumer to issue
a basicCancel for its consumer tag(s) (one per queue) and waits for all the
cancelOKs and close its channel. When all the consumer instances have
stopped, the container stops.

The architecture is such that we allow any pre-fetched messages that have
already been passed to the container to process before the cancel is
issued, while preventing any new deliveries. Hence, any prefetched messages
in the container complete processing, while those still in the rabbit
client, and not yet handed over to the container will be un-acked and
redelivered later.


On Wed, Apr 2, 2014 at 4:35 PM, Jason McIntosh <mcintoshj at gmail.com> wrote:

> Real quick sample code from the Spring AMQP site:
>
>
>     ConnectionFactory cf = new CachingConnectionFactory();
>
>     // set up the queue, exchange, binding on the broker
>     RabbitAdmin admin = new RabbitAdmin(cf);
>     Queue queue = new Queue("myQueue");
>     admin.declareQueue(queue);
>     TopicExchange exchange = new TopicExchange("myExchange");
>     admin.declareExchange(exchange);
>     admin.declareBinding(
>         BindingBuilder.bind(queue).to(exchange).with("foo.*"));
>
>     // set up the listener and container
>     SimpleMessageListenerContainer container =
>             new SimpleMessageListenerContainer(cf);
>     Object listener = new Object() {
>         public void handleMessage(String foo) {
>             System.out.println(foo);
>         }
>     };
>     MessageListenerAdapter adapter = new MessageListenerAdapter(listener);
>     container.setMessageListener(adapter);
>     container.setQueueNames("myQueue");
>     container.start();
>
>     // send something
>     RabbitTemplate template = new RabbitTemplate(cf);
>     template.convertAndSend("myExchange", "foo.bar", "Hello, world!");
>     Thread.sleep(1000);
>     container.stop();
>
>
> ON a war, you add shutdown hooks to the web.xml file.  In a non-web environment, there are shutdown hooks through the Runtime:
> http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html
>
> In the end, they all call container.shutdown:
> http://docs.spring.io/spring-amqp/docs/1.2.1.RELEASE/api/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.html
>
> Code for that I found here:
> http://grepcode.com/file/repo1.maven.org/maven2/org.springframework.amqp/spring-rabbit/1.0.0.RELEASE/org/springframework/amqp/rabbit/listener/SimpleMessageListenerContainer.java
>
> The spring libraries are fantastic for RabbitMQ work (though sometimes there are some headaches on "Which factory is this? Which MessageProperties do I use?" kinda stuff, but overall they're not bad and they're getting better.  I tend to be very careful on how much abstraction I add to my systems (hence why Groovy drives me nuts), but overall spring is has been very clean implementation wise.
>
> Jason
>
>
>
>
>
> On Wed, Apr 2, 2014 at 3:17 PM, Bertrand Guay-Paquet <
> bernie at step.polymtl.ca> wrote:
>
>>  Hi Jason,
>>
>> Thanks for the hint, but I'm unfortunately not using Spring for this. Do
>> you know how Spring achieves this "shutdown" command? I don't know Spring
>> at all but I'll have a look at their doc.
>>
>> Regards,
>> Bertrand
>>
>>
>> On 02/04/2014 4:10 PM, Jason McIntosh wrote:
>>
>>  We use consumers here with the spring libraries.  If you use them,
>> there's a "Shutdown" command you can call as needed.  We've had pretty good
>> luck with it so far.  The spring consumer stuff manages how many consumers
>> are running, connection threading, etc. - and it has very good shutdown
>> hooks.
>>  Jason
>>
>>
>> On Wed, Apr 2, 2014 at 3:02 PM, Bertrand Guay-Paquet <
>> bernie at step.polymtl.ca> wrote:
>>
>>> Hello,
>>>
>>> I'm using the RabbitMQ Java client API and need some guidance on the
>>> proper application shutdown procedure.
>>>
>>> Here's how I start the application:
>>> 1-Create a Connection
>>> 2-Create different types of consumers, each with its own channel, and
>>> call channel.basicConsume("queue", false, consumer)
>>> 3-Let it all run
>>>
>>> This works great, but I can't figure out how to cleanly shutdown the
>>> application. If I simply close the Connection, each created channel
>>> immediately (or soon enough) becomes invalid and any Consumer currently
>>> doing some work fails when trying to ack their current message or perform
>>> any other action on the channel. I'd like to let the consumers finish
>>> whatever message they're processing and then close everything down. I guess
>>> I need to keep track of the created Consumers and somehow signal them to
>>> stop accepting new messages and after they're all done with their current
>>> job, close the connection? Is that possible or is there another way? I
>>> haven't found any management methods for the consumer classes to control or
>>> query their status.
>>>
>>> The information I found so far is related to manually created threads
>>> that poll the queues to process messages. In that case, it's really easy
>>> because I can just set a flag on each runnable to exit after processing
>>> their current message and join on all the threads before closing the
>>> underlying connection. So this leads me to ask, as a side note: are
>>> Consumers the way to go to use RabbitMQ in real-world scenarios or should I
>>> poll on the queues? It seems to me that Consumers would be the better
>>> choice (polling is bad), but if they're less powerful, perhaps they're not
>>> a silver bullet in my case.
>>>
>>> Thank you,
>>> Bertrand
>>> _______________________________________________
>>> rabbitmq-discuss mailing list
>>> rabbitmq-discuss at lists.rabbitmq.com
>>> https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
>>>
>>
>>
>>
>> --
>> Jason McIntosh
>> https://github.com/jasonmcintosh/
>> 573-424-7612
>>
>>
>> _______________________________________________
>> rabbitmq-discuss mailing listrabbitmq-discuss 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
>>
>>
>
>
> --
> Jason McIntosh
> https://github.com/jasonmcintosh/
> 573-424-7612
>
> _______________________________________________
> rabbitmq-discuss mailing list
> rabbitmq-discuss at lists.rabbitmq.com
> https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20140402/bd298f50/attachment.html>


More information about the rabbitmq-discuss mailing list