Search code examples
javaservletsmonitoringjmx

Java monitoring: JMX vs. Servlets


I've learned a lot about JMX over the past couple of years and have built some pretty fancy MBeans for my web applications. However, I'm not sure I have a good answer to a pretty basic question:

Why use JMX over simple HTTP servlets?

My current web applications offer redundant monitoring options: I can access the data that needs to be monitored via JMX with a client like JConsole or I can access that same data in XML format via a servlet. I don't see a strong reason to use one method over another, but the servlet method does have the major advantage of being readable by a simple http client / web browser.

I can see how JMX would be quite useful for Java applications that aren't web apps, but I can't see any advantage to using JMX for a web app.


Solution

  • Why use JMX over simple HTTP servlets?

    From my standpoint, JMX is better for 3 reasons:

    1. It requires less code to enable monitoring points.
    2. It deals with Java serialized objects end-to-end so there is better data consistency.
    3. It works with programs that are not servlet based (as you mentioned).

    JMX offers a much easier interface to specific data items. You can certainly write the same functionality in a number of servlets, but it is easier for me to expose those using JMX.

    For example, if you are using Spring then you can use the org.springframework.jmx.export annotations (@ManagedResource, @ManagedAttribute, etc.) to mark up your classes. I've also published my SimpleJmx framework so you can easily expose attributes and operations with just a couple annotations independent of Spring. For example:

    @JmxResource(domainName = "j256", objectName = "lookupCache")
    public class LookupCache {
    
        // this can also be done as @JmxAttributeMethod on the getter/setters
        @JmxAttributeField(description = "Number of hits in the cache")
        private int hitCount;
        ...
    
        @JmxOperation(description = "Flush the cache")
        public void flushCache() {
           ...
        }
    }
    

    I have a fully working example program to see how it works. So all you need to do to expose a value or operation is add an annotation to the class and each attribute and/or method. The code to publish it using SimpleJmx looks like the following. Spring is similar albeit with beans:

    // create a new server listening on port 8000
    JmxServer jmxServer = new JmxServer(8000);
    jmxServer.start();
    // register our lookupCache object defined above
    jmxServer.register(lookupCache);
    

    To get similar functionality in servlets would take a lot more code than just annotations. That said, there may exist frameworks which provide similar functionality in servlet land that I don't know about.

    Some more notes:

    • There are probably better monitoring tools that grok HTTP/HTML but there are also a ton of distributed JMX monitoring applications. Probably a toss up.
    • Being able to programmatically get objects from JMX servers is a plus as opposed to just strings from a servlet page. SimpleJmx also supports a simple JMX client although better ones exist out there.
    • Obviously a lot of other worthwhile data is already published by the JVM by default: VM settings, thread details, memory information, etc..