11

I want to create a java class , which has the sole purpose of checking the status of an ActiveMQ broker (or connectivity to an ActiveMQ broker as an outage may be defined as the client losing network connectivity as well).

so basically there would be a thread running after every few seconds to check the status of the broker and if there broker is down, I want to do some specific task of mailing the support group and stuff like that.

The examples online are not detailed enough to explain how the above can be achieved.

Has someone already done this, or can suggest a nice way to make this happen??

Thanks, Neeraj

Neeraj
  • 8,408
  • 8
  • 41
  • 69

3 Answers3

9

The following will also work to check if ActiveMQ is up and running:

try {
   ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(url);
   // set transport listener so that active MQ start is notified.
   factory.setTransportListener(transportListenerObject); 
   Connection connection = factory.createConnection();
   // This will throw error if activeMQ is not running.
   connection.setClientID("my_client_id"); 
} catch (JMSException ex) {
    if (ex.getLinkedException() instanceof IOException) {
        // ActiveMQ is not running. Do some logic here.
        // use the TransportListener to restart the activeMQ connection
        // when activeMQ comes back up.
    } else {
        // Something seriously went wrong with the factory or connection
        // creation. Abort the process here, as nothing can be done.
        // Log the error and troubleshoot.
    }
}
Anand
  • 541
  • 3
  • 9
8

Send a Testmessage to the broker:

try {
    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
    Connection conn = factory.createConnection(user, password);
    Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageProducer producer = session.createProducer("test");
    MessageConsumer consumer = session.createConsumer("test");
    consumer.setMessageListener(this); // class that implements MessageListener
    conn.start();
    TextMessage message = new ActiveMQTextMessage();
    message.setText("TestMessage");
    producer.send(message);
} catch (JMSException e) {
    // somethings very wrong
}

connect, send message, if you recieve message: all is fine. if not....

thats what i do. In addition i do some other stuff:

  • listen to several Advisory Topics to receive important events (like Advisory.FULL) that are important indicators that somethings wrong.
  • regularly get the broker statistics from the statistics plugin to monitor message memory size and message store.
  • configure a dead letter queue so i know when a message was rejected by the consumer.
magiccrafter
  • 5,175
  • 1
  • 56
  • 50
Laures
  • 5,389
  • 11
  • 50
  • 76
  • Would the catch block be executed even if the broker is down and doesnt respond?or if there is a huge network delay? – Neeraj Oct 18 '11 at 14:23
  • when the broker is down the createConnection call fails and the exception will be caught. if you just want to check the network delay you will have to manually ping the server from a remote destination. the loopback device is never slow. – Laures Oct 18 '11 at 14:33
7

I needed a solution for the same question, that's why I read more about it and made several tests.

Sending a test message (as Laures suggested) can be a problem in some environments.

The "normal" way would be to set a TransportListener (as Anand suggested), but really implement the provided interface and react on the reported events.

For other ActiveMQ newbies (as I was until last month) I post a sample startup implementation. It just writes logging for each event. In a real environment one can think about a reconnect trial in transportInterupted() until transportResumed() or similar and many things more ...

import java.io.IOException;

import org.apache.activemq.transport.TransportListener;
import org.apache.log4j.Logger;

class ConnectionStateMonitor
  implements TransportListener
{
  private static final Logger log = Logger.getLogger(ConnectionStateMonitor.class);

  @Override
  public void onCommand(Object command)
  {
    log.debug("Command detected: '" + command + "'");
  }

  @Override
  public void onException(IOException exception)
  {
    log.error("Exception detected: '" + exception + "'");
  }

  @Override
  public void transportInterupted()
  {
    log.error("Transport interuption detected.");
  }

  @Override
  public void transportResumed()
  {
    log.info("Transport resumption detected.");
  }
}

The TransportListener can be set e.g.:

ActiveMQConnection connection = (ActiveMQConnection) _factory.createConnection();
...
connection.addTransportListener(new ConnectionStateMonitor());

Have fun!

Community
  • 1
  • 1
Mayoares
  • 1,234
  • 2
  • 13
  • 21
  • In addition, you can also use failover in the connection URI, "failover:tcp://host:port ". This will tell the client to automatically reconnect if there is a socket exception: http://activemq.apache.org/how-can-i-support-auto-reconnection.html – Jason Huntley Jun 25 '15 at 17:56