用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