What is the best way to safely terminate a Java application using RabbitMQ users

We have a standalone java application that does some background processing on a Debian machine. The work with which he must work is sent via RabbitMQ messages.

When a Java application needs to be updated, we need to stop it (kill). But we must be sure that none of the users are currently processing the message. What, in your experience, is the best way to achieve this?

We tried to send a "SHUTDOWN" message to the consumer, but we cannot close the queue or channel ?! It freezes the app! Or is there another solution where we could, for example, disconnect an application without executing the kill command on Linux?

Thank you to share your experience with you.

Hi

+7
source share
2 answers

The RabbitMQ Java libraries do not provide (AFAIK) anything that automatically delays the completion of a consumer process while some messages are still being processed. So you have to do it yourself.

If your application can tolerate it, just turn it off. Any message that was not confirmed at this point will remain in the queue at the broker and will be resent when the consumer returns.

If you cannot tolerate this, and you absolutely must make sure that all message processing is completed, then you need to follow the tips similar to what was found in this answer and follow these steps in the shutdown handler:

  • Set the "all threads should exit" checkbox to true
  • Join each thread in the thread pool
  • Exit gracefully

This means that each of your message processing threads (assuming you have multiple threads processing messages at the same time) must follow this general pattern:

  • Pull the message out of the queue and process it
  • Enter the message that has just been processed.
  • If the "all threads should exit" flag is true, exit the thread function
  • Rinse, repeat

Hope this helps.

+2
source

Here I accept it.

I created my subclass DefaultConsumer (BasicConsumer), which provides isCancelled () and implements handleCancelOk (), which sets the "unchecked flag" to true.

Initial Sequence:

consumers = new ArrayList<BasicConsumer>(); consumers.add(...) 

Stop sequence:

 // Cancel all consumers for (BasicConsumer consumer : consumers) { try { consumer.getChannel().basicCancel(consumer.getConsumerTag()); } catch (Exception e) { // report } } // Wait for all consumers to be cancelled Timeout timeout = ...; while (!consumers.isEmpty() && !timeout.isElapsed()) { // Remove cancelled consumers for (Iterator<BasicConsumer> iterator = consumers.iterator(); iterator.hasNext();) { if (iterator.next().isCancelled()) iterator.remove(); } } // Here we could force-close the remaining timed-out consumers if we // used our own ExecutorService by shutting down all of its threads. connection.close(); 

RabbitMQ ML Relevant Stream: How to close a Java application using Consumers?

0
source

All Articles