In this section we describe the JMX Notifiction model and its use with JMX Monitors
The JMX Notifications are management events that are transmitted by JMX components to other interested components. Those other components may be JMX components or may be components of the managed application itself.
The JMX Notification Model has five key elements:
The JMX Notification Model is described in detail in the JMX Specification. Please refer to the specification for more information.
Notifictions allow us to complete the management feedback loop. In the previous sections we instrumented a simple HTTP daemon with MBeans and then set up monitors on attributes of those MBeans. Now we need to listen for the notifications that our monitors will generate, e.g., when thresholds are crossed, and take appropriate action.
A notification listener is just a Java class that implements the
JMX NotificationListener
interface. Notification listeners are added to MBeans via one of the
MBeanServer's addNotificationListener()
methods. Which
one you use depends on whether your listener is an MBean registered
with the MBeanServer or an object reference to an instance of an
appropriate Java class. We will take the latter approach with our HTTP
daemon defining classes that know how to react to handlerPoolGauge and
logfileCounter notifications. The code below illustrates how instance
of these classes are added to the respective Gauge and Counter
monitors:
HandlerPoolManager hpm = new HandlerPoolManager(mbs, handlersObjectName);
HandlerPoolManager.Filter hpmf = new HandlerPoolManager.Filter("jmx.monitor.gauge.low");
mbs.addNotificationListener(handlerPoolGaugeObjectName, hpm, hpmf, null);
LogfileManager lm = new LogfileManager(mbs, logfileObjectName);
LogfileManager.Filter lmf = new LogfileManager.Filter("jmx.monitor.counter.threshold");
mbs.addNotificationListener(logfileCounterObjectName, lm, lmf, null);
Both of our manager classes contain a nested class that
implements the NotificationFilter interface. If we
don't add a filter when we add the listener the manager will receive
all notifications generated by the MBean. Here we are only interested
in the situation where the handler pool becomes low and the logfile
size has grown too large.
Finally, we need to think about what we want to do when we receive
notifications that we're listening for. In the case of the logfile we
will invoke the LogFileMBean interface's rollOver()
method. rollOver
renames the current log file and then
creates a new, empty, log file. Here's the LogfileManager's
handleNotification()
method:
public void handleNotification(Notification notification, Object handBack) {
mbs.invoke(logfile, "rollOver", null, null);
}
For the handler pool let's increase the size of the pool by 25%
whenever we get a low threshold notification:
public void handleNotification(Notification notification, Object handBack) {
int size =((Integer) mbs.getAttribute(handlerPool, "Size")).intValue();
Attribute nextSize = new Attribute("Size", new Integer((int) (size * 1.25)));
mbs.setAttribute(handlerPool, nextSize);
}
Now the management feedback loop is closed. Our HTTP daemon is a self-managing application. Of course situations could arrise in which human intervention via a management console would be necessary. As discussed in the introduction that is the role of the, as yet undefined, JMX Distributed Services layer. While by no means addressing all the Distributed Services issues the TMX4J package does provide an RMI Connector Server and an HTTP Protocol Adapter to give you the ability to access your instrumentation "from the outside".