用Commons Modeler 開發JMX應用
Modeler組件是Jakarta Commons 項目針對Model MBeans提供的一個便利的開發組件。
首先介紹一下基本的概念:Managed bean簡稱Mbean,是對可被管理的資源的抽象定義,ModelBean是JMX定義的Mbean中動態和靈活的一種。但是要實現它開發人員必須設置大量的Metadata信息。Modeler組件針對ModelBean的開發,通過采用xml來定義metadata的方式來簡化了ModelBean的開發強度,同時它和提供了注冊的支持和缺省的ModelMbean的支持。這些我們都將在下面的例子中看到。另外關于JMX和ModelMBean的介紹有很多可以參考。這里都不提了。
下面主要通過例子來寫一下如何使用它進行JMX開發。
在實際開發中,我們都是首先定義需要被管理的資源對象,然后把它注冊到MBeanServer中進行發布。最后再通過客戶端訪問。
所以我的例子也通過這個來完成。
1. 資源對象和MBean的實現
首先編寫一個需要管理的對象。該對象很簡單有一個屬性和一個操作。
public class TestBean {
private String oneAttr;
public String getOneAttr(){
return "one attribute be testing";
}
public void setOneAttr(String attr){
this.oneAttr = attr;
}
public String toString(){
return "toString be testing";
}
}
根據需要被管理的要求編寫Mbeans-descriptors.xml
<?xml version="1.0"?>
<mbeans-descriptors>
<mbean name="TestBean"
description="the test bean"
domain="mydomain"
group="testGroup"
type="mbeans.TestBean">
<attribute name="oneAttr"
description="one Attr to be tested"
type="java.lang.String"
writeable="true"/>
<operation name="toString"
description="one Oper to be tested"
impact="INFO"
returnType="String">
</operation>
</mbean>
</mbeans-descriptors>
通過這個xml文件的定義就描述了ModelBean所需要的metadata信息和一個基本的ModelMBean的實現。
關于這個xml文件有幾個需要說明的地方:
<mbean>的屬性classname,name和type,
name屬性是每個Mbean被Registry對象注冊的對象名。
type屬性是是真正被管理資源的全名(包括包名)。
classname屬性是用戶擴展的用于實現代理功能的ModelMbean的全名,如果不提供Modeler會使用BaseModelMBean;如果提供了代理的ModelMBean對象,在使用時可以使用如下的代碼樣本訪問他所代理的資源對象。
Function foo(){
TestObject object = this.resource; //得到所代理的對象。
Object.foo(); //具體實現的調用。
}
Mbeans-descriptors.xml的其他的部分都比較好理解,具體參考DTD就可以了。
下面我們就要把完成MBeanServer的實現和Mbean的注冊。
2. MBeanServer的實現和MBean的注冊
MBeanServer的實現代碼:
registry = Registry.getRegistry();
InputStream stream = MyMBeanServer.class
.getResourceAsStream("Mbeans-descriptors.xml");
registry.loadRegistry(stream);
stream.close();
mserver = registry.getMBeanServer();
通過Modeler組件提供的Registry對象,可以很方便的完成MBeanServer的創建。
MBean的注冊代碼:
/*創建被管理的資源實例*/
TestBean bean = new TestBean();
/*Modeler組件提供的對managedbean配置信息的封裝對象,通過它建立資源和ModelMBean的聯系*/
ManagedBean managed = registry.findManagedBean("TestBean");
String domain = managed.getDomain();
/*得到ModelMbean*/
ModelMBean mbean = managed.createMBean(bean);
/*創建ObjectName*/
ObjectName oname = new ObjectName(domain+":test=zcx");
/*注冊MBean*/
mserver.registerMBean(mbean,oname);
3. MBeanServerConnector的實現。
在JMXRemoteAPI 發布之后,Agent需要提供ConnectorServer,我們可以這樣注冊一個JMXMP的ConnectorServer.
/*定義JMXServiceURL這個對象是客戶端和服務器聯系的關鍵*/
JMXServiceURL address = new JMXServiceURL("jmxmp", null, 7777);
connectorSrv=JMXConnectorServerFactory.newJMXConnectorServer(address, null, null);
ObjectName csName = new ObjectName(":type=cserver,name=mycserver");
mserver.registerMBean(connectorSrv, csName);
connectorSrv.start();
在這里需要說明的是通過JMXServiceURL的可以定義ConnectorServer的類型是JMXMP,RMI或者其他什么類型。按照規范規定這個JMXServiceURL應該在服務器端通過JNDI或者SLP等進行發布。然后客戶端通過相應的訪問得到這個對象,進行通信。如何通過JNDI訪問這個對象,我就不在這里寫了。
4. MBeanServerAdaptor的實現。
madaptor = new HtmlAdaptorServer();
mserver.registerMBean(madaptor,new,ObjectName("adaptor:protocol=HTTP"));
madaptor.setPort(8888);
madaptor.start();
5. MBeanClient的實現。
使用http瀏覽器,我們可以通過HtmlAdaptorServer訪問MBean。
另外我們通過JMXRemoteAPI也可以在客戶端訪問MBean。
客戶端代碼如下:
JMXServiceURL address = new JMXServiceURL("jmxmp","zcx" , 7777);
connector = JMXConnectorFactory.connect(address);
mbsConn = connector.getMBeanServerConnection();
通過MBeanServerConnection對象我們可以對MBean進行各種操作。
到這里一個簡單的JMX的應用流程就完成了。J