Tuesday, August 17, 2010

managing ActiveMQ with JMX APIs

here is a quick example of how to programmatically access ActiveMQ MBeans to monitor and manipulate message queues...

first, get a connection to a JMX server (assumes localhost, port 1099, no auth)
note, always cache the connection for subsequent requests (can cause memory utilization issues otherwise)

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url);
MBeanServerConnection conn = jmxc.getMBeanServerConnection();

then, you can execute various operations such as addQueue, removeQueue, etc...

String operationName="addQueue";
String parameter="MyNewQueue";
ObjectName activeMQ = new ObjectName("org.apache.activemq:BrokerName=localhost,Type=Broker");
if(parameter != null) {
    Object[] params = {parameter};
    String[] sig = {"java.lang.String"};
    conn.invoke(activeMQ, operationName, params, sig);
} else {
    conn.invoke(activeMQ, operationName,null,null);
}

also, you can get an ActiveMQ QueueViewMBean instance for a specified queue name...

ObjectName activeMQ = new ObjectName("org.apache.activemq:BrokerName=localhost,Type=Broker");
BrokerViewMBean mbean = (BrokerViewMBean) MBeanServerInvocationHandler.newProxyInstance(conn, activeMQ,BrokerViewMBean.class, true);

for (ObjectName name : mbean.getQueues()) {
    QueueViewMBean queueMbean = (QueueViewMBean)
           MBeanServerInvocationHandler.newProxyInstance(mbsc, name, QueueViewMBean.class, true);

    if (queueMbean.getName().equals(queueName)) {
        queueViewBeanCache.put(cacheKey, queueMbean);
        return queueMbean;
    }
}

then, execute one of several APIs against the QueueViewMBean instance...

queue monitoring - getEnqueueCount(), getDequeueCount(), getConsumerCount(), etc...

queue manipulation - purge(), getMessage(String messageId), removeMessage(String messageId), moveMessageTo(String messageId, String destinationName), copyMessageTo(String messageId, String destinationName), etc...

summary
The APIs can easily be used to build a web or command line based tool to support remote ActiveMQ management features. That being said, all of these features are available via the JMX console itself and ActiveMQ does provide a web console to support some management/monitoring tasks.

See these pages for more information...

http://activemq.apache.org/jmx-support.html
http://activemq.apache.org/web-console.html


9 comments:

  1. thanks for posting this info..this is super helpful

    ReplyDelete
  2. If you are running the activeMQ example code, you have to make a change to the config file:





    by default, createConnector="false", which will lead you to getting an exception:

    java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
    java.net.ConnectException: Connection refused]
    at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:342)
    at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:267)
    at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:226)

    ReplyDelete
  3. What do I need to change the config file to ?

    Jessica

    ReplyDelete
  4. if you are using ActiveMQ 4+, then you don't need to change the config file at all (JMX is enabled by default). see http://activemq.apache.org/jmx.html for more information...

    ReplyDelete
  5. Hi Ben,
    I am trying your example, and always ends up with "java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.NameNotFoundException: jmxrmi" . I think I don't have JMX server running. How/where to run JMX server? Do I need to create JMX server?

    ReplyDelete
  6. Hi Ben,

    I have successfully made the program run. I did not know that activemq is hosting jmx server itself. Thanks for sharing knowledge.

    Lwin

    ReplyDelete
    Replies
    1. Hii Ben,Lwin
      i am trying this example, i got one exception like lwin got before but i resolve by change the config file createConnector="true". then i got one exception like "InstanceNotFoundException" : org.apache.activemq:Type=Broker,BrokerName=localhost.i changed in config file useJmx="true".but still i'm not able to resolve it. version-activemq 5.8.0

      Delete
  7. hi ben
    i got the answer.ObjectName activeMQ = new ObjectName("org.apache.activemq:BrokerName=localhost,Type=Broker"); in this BrokerName 'B' sould be small 'b' i.e brokerName same for "Type" will be "type". otherwise it will give "instancenotfoundexception".

    ReplyDelete
    Replies
    1. Thanks for the update on this. I was running into the same issue and that fixed it. Much appreciated.

      Delete