作过 Java 平台下的应用服务器监控的对 JMX 应该不会陌生,简单说 JMX 就是提供了一个标准的管理方案的框架。这里所说的管理的含义包括监控平台运行情况、应用级别配置资源、收集应用统计数据、调试、监视服务器性能,JMX 容许你将全部的资源(硬件和软件)打包成 java 对象,而后将他们暴露在分布式环境中,而且 JMX 提供了一个机制,能够很简单的将既存的管理协议,如 SNMP ,映射到 JMX 本身的管理结构中。html
本文重点不是介绍 JMX ,而是分析 Tomcat 7 中是如何用 JMX 来提供管理功能的,若是对 JMX 并不熟悉能够先 Google 一下,了解一下这个技术,网上已经有一些中文技术博客的介绍,如 BlogJava 里 子在川上曰 的 JMX 一步步来、《JMX IN ACTION》的一些翻译文章。固然,最权威的仍是看看 oracle 的官方文档,这里提供JMX 1.4 规范的官方连接。java
先来看下 Tomcat 7里由 JMX 提供的管理功能,在 Tomcat 启动完以后能够用 jconsole 来访问: 程序员
JMX 标准提供了四种不一样的 MBean :apache
Standard MBean,该 MBean 直接实现用于管理对象的方法,既能够经过实现一个由程序员定义的、类名以 “MBean” 结束的接口,也可使用一个以一个类做为构造函数参数的 Standard MBean 实例,加上一个可选的接口类规范。这个接口能够开放用于管理的部分对象方法。数组
Dynamic MBean,该 MBean 用属性访问器动态地访问属性,并用一个通常化的 invoke() 方法调用方法。可用的方法是在 MBeanInfo 接口中指定的。这种方式更灵活,可是不具备像 Standard MBean 那样的类型安全性。它极大地下降了耦合性,可管理的 POJO(纯粹的老式 Java 对象)不须要实现特定的接口。安全
Model MBean,该 MBean 提供了一个改进的抽象层,并扩展了 Dynamic MBean 模型以进一步减小对给定实现的依赖性。这对于可能使用多个版本的 JVM 或者须要用松散耦合管理第三方类的状况会有帮助。Dynamic MBean 与 Model MBean 之间的主要区别是,在 Model MBean 中有额外的元数据。bash
Open MBean,该 MBean 是受限的 Model MBean,它限制类型为固定的一组类型,以获得最大的可移植性。经过限制数据类型,可使用更多的适配器,而且像 SMTP 这样的技术能够更容易适应 Java 应用程序的管理。这种变体还指定了数组和表等标准结构以改进复合对象的管理。服务器
在 Tomcat 7 中能够看到标准 MBean(Standard MBean)和动态 MBean(Dynamic MBean)的使用,本文就介绍这两种 MBean。先来看下比较简单的标准 MBean:oracle
在 Tomcat 的启动类org.apache.catalina.startup.Bootstrap的createClassLoader
方法最后一部分:框架
ClassLoader classLoader = ClassLoaderFactory.createClassLoader
(repositories, parent);
// Retrieving MBean server
MBeanServer mBeanServer = null;
if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
} else {
mBeanServer = ManagementFactory.getPlatformMBeanServer();
}
// Register the server classloader
ObjectName objectName =
new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
mBeanServer.registerMBean(classLoader, objectName);
复制代码
从ClassLoaderFactory.createClassLoader
方法的最后一部分实现代码:
return AccessController.doPrivileged(
new PrivilegedAction<StandardClassLoader>() {
@Override
public StandardClassLoader run() {
if (parent == null)
return new StandardClassLoader(array);
else
return new StandardClassLoader(array, parent);
}
});
复制代码
能够看出上面的 classLoader 对象实际是org.apache.catalina.loader.StandardClassLoader
类的实例。看这个类的定义:
public class StandardClassLoader
extends URLClassLoader
implements StandardClassLoaderMBean
复制代码
它实现了一个StandardClassLoaderMBean 接口。从这里就能够看出最上面的代码mBeanServer.registerMBean
中注册的实际上就是一个Standard MBean。只是这个标准 MBean 很没意思,一个方法都没开放出去管理,因此 jconsole 里只能看到 MBean 的描述信息,看不到它的属性、方法: