Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to safely end a java application with running RabbitMQ consumers

Tags:

java

rabbitmq

We have a standalone java application doing some background processing on a Debian machine. The jobs it has to handle are send through RabbitMQ messages.

When the java application needs to be upgraded we need to stop it (kill it). But we have to be sure that no consumers are currently processing a message. What is, in your experience, the best way to achieve this?

We tried to send a 'SHUTDOWN' message to a consumer, but we can't seem to close the queue or channel?! It freezes the application! Or is there another solution where we could for example auto shutdown the application, without doing the kill command in linux?

Thx to share you experience.

Greetings

like image 660
Toni Van de Voorde Avatar asked Jul 14 '11 20:07

Toni Van de Voorde


People also ask

How do I close consumer RabbitMQ?

You can kill connections to the RabbitMQ broker using the rabbitmqctl tool (see the man page) or by using the Web UI. You could also purge and delete the queue which belonged to the rogue consumer. However, you can't kill the consumer process itself using those tools.

Does RabbitMQ use Java?

There are a number of clients for RabbitMQ in many different languages. We'll use the Java client provided by RabbitMQ. Download the client library and its dependencies (SLF4J API and SLF4J Simple).


1 Answers

The RabbitMQ Java libraries do not provide (AFAIK) anything which would automatically postpone the shutdown of a consumer process while some messages are still being processed. Therefore you'll have to do this yourself.

If your application can tolerate it, just shut down. Any message which had not been acknowledged at that point will remain on the queue within the broker and will be re-delivered when the consumer comes back up.

If you can't tolerate that and you absolutely must ensure that all in-progress message processing finishes, then you need to follow advice similar to what's found in this answer and do the following in your shutdown handler:

  1. Set an "all threads should exit" flag to true
  2. Join with each of the threads in your thread pool
  3. Exit gracefully

That implies that each of your message processing threads (assuming you have multiple threads processing messages concurrently) need to follow this general pattern:

  1. Pull a message from the queue and process it
  2. Ack the message which was just processed
  3. If the "all threads should exit" flag is true, exit the thread function
  4. Rinse, repeat

Hope that helps.

like image 172
Brian Kelly Avatar answered Sep 18 '22 14:09

Brian Kelly