目录1.概述2.如何开启tomcat的JMX3.tomcat如何实现JMX的源码分析1.概述本文是博主JAVA监控技术系列文章的第二篇前面一篇文章中我们介绍了JAVA监控技术的基石——jmx【JMX】JAVA监控的基石-CSDN博客本文我们将从使用和源码实现两个方面聊一下jmx的落地实现范例——tomcat中的jmx。tomcat作为一个web server其选用jmx来实现监控功能。之所以选择jmx是因为jmx是java se原生的能力不需要第三方依赖在web server这种基础组件中选用原生的技术可以避免很多三方依赖带来的不便。2.如何开启tomcat的JMXjmx是由JVM来支持实现的标准所以开启jmx本质上就是通过配置启动参数的方式来实现的例如以下是一个简单的 Java 命令启用了 JMX 监听并配置了 JMX 服务器的地址和端口java -Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.port9999-Dcom.sun.management.jmxremote.authenticatefalse-Dcom.sun.management.jmxremote.sslfalse-jar myapplication.jartomcat本质也是个Java程序所以也是通过配置启动参数来开启jmx的。本文是基于Windows环境来配置的Linux环境其实也大差不差。配置Catalina.bat在Execute The Requested Command下面加上下面的配置set JAVA_OPTS%JAVA_OPTS% -Djava.rmi.server.hostname192.168.56.1 -Dcom.sun.management.jmxremote.port9999 -Dcom.sun.management.jmxremote.rmi.port9999 -Dcom.sun.management.jmxremote.authenticatefalse -Dcom.sun.management.jmxremote.sslfalse然后启动tomcat打开jconsole连接上我们启动的这个tomcatMBean列表里面可以看到tomcat的所有MBean对tomcat源码熟悉的读者会发现tomcat的核心组件都以MBean的方式被注册进JMX Server中了。3.tomcat如何实现JMX的源码分析首先博主去github上下载了tomcat7.0.105版本的源码。前面我们聊过jmx要使用jmx就要先注册相关的MBean。tomcat里面有一个jmxEnabled接口这个接口就是用来实现MBean的注册的。它定义了两个方法一个用来注册MBean一个用来卸载MBean。这个接口的实现类是LifecycleMBeanBase这个类里实现了注册和卸载MBean的方法。对tomcat源码有了解的读者对这个类会很熟悉当然不了解也别怕LifecycleMBeanBase这个类是tomcat中用来管理各个组件的生命周期的也就是说这个组件里会实现一些在各个组件初始化或者销毁的时候要做的额外动作。来我们好好读一下这里的源码protected void initInternal() throws LifecycleException { ? ? ? // If oname is not null then registration has already happened via ? ? ? // preRegister(). ? ? ? if (oname null) { ? ? ? ? ? 获取MBeanServer ? ? ? ? ? mserver Registry.getRegistry(null, null).getMBeanServer(); //注册MBean ? ? ? ? ? oname register(this, getObjectNameKeyProperties()); ? ? ? } ? } //注册MBean的方法 ? protected final ObjectName register(Object obj, ? ? ? ? ? String objectNameKeyProperties) { ? ? ? ? // Construct an object name with the right domain ? ? ? StringBuilder name new StringBuilder(getDomain()); ? ? ? name.append(:); ? ? ? name.append(objectNameKeyProperties); ? ? ? ? ObjectName on null; ? ? ? ? try { ? ? ? ? ? on new ObjectName(name.toString()); ? ? ? ? ? //将自己注册到MBeanServer中 ? ? ? ? ? Registry.getRegistry(null, null).registerComponent(obj, on, null); ? ? ? } catch (MalformedObjectNameException e) { ? ? ? ? ? log.warn(sm.getString(lifecycleMBeanBase.registerFail, obj, name), ? ? ? ? ? ? ? ? ? e); ? ? ? } catch (Exception e) { ? ? ? ? ? log.warn(sm.getString(lifecycleMBeanBase.registerFail, obj, name), ? ? ? ? ? ? ? ? ? e); ? ? ? } ? ? ? ? return on; ? }