作過 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 的描述信息,看不到它的屬性、方法: