Remote Monitoring of Servlet Container through Firewalls
The jconsole application that is included with the standard JDK can be used to monitor remote JVM’s. The default JMX server that comes with Java uses dynamic ports to determine the JMX connector server port. This makes it next to impossible to monitor remote JVM’s, since remote JVM’s are usually behind some kind of firewall. The standard strategy for remote monitoring in these cases is to write a simple class that creates and starts a JMX connector server on a pre-defined port, which can then be configured for access in the firewall rules. Some additional configuration is also necessary to enable remote monitoring, usually through system properties specified to the JVM at startup.
The main requirement is to create a servlet that starts a custom JMX connector service that listens on a pre-configured port when the JVM is started. JMXServer.groovy is a simple servlet that we have used in numerous instances to monitor our Tomcat instances. We also configure the servlet to be loaded by the servlet container on startup rather than on request. The final step is to allow access to the configured JMX service and connector ports through the firewall.
The steps here relate to configuring Tomcat to load our servlet on startup.
- Add the following to the web.xml file for the web app to configure the servlet for auto load.
- Configure JVM system properties in catalina.sh. Note that the RMI hostname setting is required on Linux
CATALINA_OPTS="$CATALINA_OPTS -Djava.rmi.server.hostname=<server name>”
- Restart Tomcat
Once Tomcat is running and the firewall rules have been added for the JMX registry and connector ports, you can run jconsole or VisualVM and connect to the remote JVM running Tomcat. An example connection URL will look similar to the following (note that the servlet logs the service URL, so you can look up the exact URL from the log file):
service:jmx:rmi://<server name>:8098/jndi/rmi://<server name>:8099/server