JMX越来越多得出现在各种技术杂志、以及社区,如ibm的 developerworks和bea的dev2dev。不仅仅是SUN,许多厂商都宣布已经或是准备支持这一技术。IBM、BEA、HP、Marcomedia(JRun)这些大的厂商,而且还有许多小的软件公司和开源项目也都加入了这一行列。为什么JMX那么受欢迎,JMX到底有那些优势只得人们去学习和理解,本文从JMX的基本架构、hellowold jmx以及spring对JMX的支持讲起,希望大家能通过本文对JMX有个基础的认识,并能通过本文为今后学习JMX打个基础
JMX中的术语:
- MBean:是Managed Bean的简称。在JMX中MBean代表一个被管理的资源实例,通过MBean暴露一系列方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。事实上,MBean就是一个Java Object,同JavaBean模型一样,外界使用反射来获取Object的值和调用Object的方法,只是MBean提供了更加容易操作的反射的使用。Mbean 包括4种类型:标准MBean、动态MBean、开放MBean、模型MBean。
- MBeanServer:MBeanServer是MBean 的容器。MBeanServer管理这些MBean,并且通过代理外界对它们的访问。MBeanServer提供了一种注册机制,通过注册Adaptor和Connector,以及MBean到MBeanServer,并且通过代理外界对它们的访问。外界可以通过名字来得到相应的MBean实例。
- JMX Agent:Agent只是一个Java进程,它包括这个MBeanServer和一系列附加的MbeanService。当然这些Service也是通过MBean的形式来发布。
- Protocol Adapters and Connectors
JMX Agent通过各种各样的Adapter和Connector来与外界(JVM之外)进行通信。同样外界(JVM之外)也必须通过某个Adapter和Connector来向JMX Agent发送管理或控制请求。Jdmk5.1中,sun提供很多Adaptor和Connector的实现
Adapter和Connector的区别在于:Adapter是使用某种协议(HTTP或者SNMP)来与JMX Agent获得联系,Agent端会有一个对象(Adapter)来处理有关协议的细节。比如SNMP Adapter和HTTP Adapter。而Connector在Agent端和client端都必须有这样一个对象来处理相应的请求与应答。比如RMI Connector。
JMX Agent可以带有任意多个Adapter,因此可以使用多种不同的方式访问Agent。
JMX基本构架:
JMX分为三层,分别负责处理不同的事务。它们分别是:
- Instrumentation 层
Instrumentation层主要包括了一系列的接口定义和描述如何开发MBean的规范。通常JMX所管理的资源有一个或多个MBean组成,因此这个资源可以是任何由Java语言开发的组件,或是一个JavaWrapper包装的其他语言开发的资源。 - Agent 层
Agent用来管理相应的资源,并且为远端用户提供访问的接口。Agent层构建在Intrumentation层之上,并且使用管理Instrumentation层内部的组件。通常Agent由一个MBeanServer组成。另外Agent还提供一个或多个Adapter或Connector以供外界的访问。 - Distributed 层
Distributed层关心Agent如何被远端用户访问的细节。它定义了一系列用来访问Agent的接口和组件,包括Adapter和Connector的描述。
Jmx 三层之间的关系:
|
MBean
|
MBean Server |
MBean
|
HTTP Adaptor |
MBean |
RMI Adaptor |
SNMP Adaptor |
Agent level |
Instrumentation level |
Connector level |
JMX Manager |
WEB Browse |
SNMP Manager |
Remote Manager
|
(图一)
本图片来自SUN JDMK的官方文档
(图二)
用另外的一个图来解释这3层之间的关系
开户(注册) |
储蓄用户(MBean) |
开户(注册) |
银行 (MBean server) |
企业贷款用户 adaptor connector |
企业贷款 manager |
(图三)
1:储蓄用户、企业贷款用户都需要到银行注册开户
2:企业贷款需要通过其开户,然后从银行拿到钱
3:拿到的钱是大部分储蓄用户存入的
JMX的开发过程也是如此
1:创建一个JMXServer
2:创建Mbean
3:把创建的Mbean 和现成的Adaptor注册到JMXServer上来
4:启动JMXServer
5:manager通过Adaptor访问Resource(Mbean)
Hello wold 开发
所需要资源:
1:jdk1.4 eclipse jdmk5.1(http://www.sun.com/software/jdmk/).spring1.2.4
2:从下载的ZIP包里面用到:jmx.jar,jmxremote.jar,jdmkrt.jar,
3:为什么要采用jmxremote.jar,jdmkrt.jar,sun提供了一些对adaptor 以及 connector供开发者使用。
本文的helloworld会采用htmladaptor以及RmiConnector的进行访问,并且用spring来展示spring对JMX的支持(展示htmladaptor)。
文件夹结构已经会用到的类
(图四)
1:通过htmladaptor对访问,程序具体解释
HelloWorldMBean是一个ingerfrace
HelloWorld是HelloWorldMBean的实现
HelloAgent里面创建了一个MbeanServer,并且把创建的Mbean和sun提供的Adaptor注册在MbeanServer上
清单一
HelloWorldMbean
public interface HelloWorldMBean {
publicvoid sayHello();
publicvoid setHello(String hello);
}
清单二
HelloWorld
public class HelloWorld implementsHelloWorldMBean {
privateString hello;
publicHelloWorld() {
this.hello= "Hello World! I am a Standard MBean";
}
publicHelloWorld(String hello) {
this.hello= hello;
}
publicvoid setHello(String hello) {
this.hello= hello;
}
publicvoid sayHello() {
System.out.println(hello);
}
}
清单三
HelloAgent
public class HelloAgent {
privateMBeanServer mbs = null;
publicHelloAgent() {
//createa MBeanServer
mbs= MBeanServerFactory.createMBeanServer("HelloAgent");
//createan adapter
HtmlAdaptorServeradapter = new HtmlAdaptorServer();
//createa MBean
HelloWorldhw = new HelloWorld("hello boys!");
ObjectNameadapterName = null;
ObjectNamehelloWorldName = null;
try{
adapterName= new ObjectName(
"HelloAgent:name=htmladapter,port=9092");
//regisetrthe adapter to the MBeanServer
mbs.registerMBean(adapter,adapterName);
//declarethe port which the adapter user
adapter.setPort(9092);
//startthe adapter
adapter.start();
helloWorldName= new ObjectName("HelloAgent:name=helloWorld1");
mbs.registerMBean(hw,helloWorldName);
}catch (Exception e) {
e.printStackTrace();
}
}
publicstatic void main(String args[]) {
//declarethe agent and start the adapter
HelloAgentagent = new HelloAgent();
}
}
必须注意的问题
1:MBean 接口的命名,必须遵循xxxMBean
2:MBean 实现类的命名必须遵循使用xxx
3:MBean 实现类必须是一个Concrete class 可以实例化,并且必须最少有一个构造函数并且为public
HtmlAdapter是sun JDMK工具包中提供的adaptor
运行上面的agent:在浏览器中输入:http://localhost:9092/
(图五)
通过浏览器你可以访问注册的helloagent,并且通过agent,可以访问到您注册到MbeanServer上的MBean
HelloAgent下面有有2个资源
1:helloworld1是注册上来的MBean
2: htmlAdpter 是注册上来的adapter
现在就可以通过浏览器来管理hellowold1这个MBean
点击name=helloWorld1就可以进来管理helloword1这个MBean
输入一个hello girls ,然后Apply
那么Helloword 里面的hello变量就成为hellogirls
(图六)
点击List of MBean operations,下面的 sayHello,就会发现控制台打印出say girls
通过Adaptor来管理MBean是不是很简单,当然我们这里管理的只是一个Standerd MBean,并且是没有notification 的机制,如果您想深入的学习,可以去亚马逊书店买一本JMX inAction
这是英文的,国内目前还没有译本。
RMI的AGENT以及通过RMIConnecterClient 对MBean的管理
清单四
RMIAgent
publicclass RMIAgent {
public static void main(String[] args) {
MBeanServer mbs =MBeanServerFactory.createMBeanServer("HelloAgent");
RmiConnectorServer connector = newRmiConnectorServer();
ObjectName connectorName = null;
try {
connectorName = newObjectName("HelloAgent:name=RMIConnector");
mbs.registerMBean(connector,connectorName);
HelloWorld hw = newHelloWorld("hello boys!");
ObjectName helloWorldName =new ObjectName(
"HelloAgent:name=helloWorld1");
mbs.registerMBean(hw,helloWorldName);
connector.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
清单五
RMIManager
publicclass RMIManager {
public static void main(String[] args) {
RmiConnectorClient client = newRmiConnectorClient();
RmiConnectorAddress address = newRmiConnectorAddress();
try {
client.connect(address);
ObjectName helloWorldName =ObjectName
.getInstance("HelloAgent:name=helloWorld1");
client.invoke(helloWorldName,"sayHello", null, null);
client.setAttribute(helloWorldName,new Attribute("Hello",
newString("hello girls!")));
client.invoke(helloWorldName,"sayHello", null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
执行RMIManager 打印出以下结果
hello boys!
hellogirls!
清单六
下面采用Spring 来演示htmladaptor
Rmi-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPEbeans PUBLIC "-//SPRING//DTDBEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="jmxMBeanExport" class="org.springframework.jmx.export.MBeanExporter">
<property name="server">
<bean class="javax.management.MBeanServerFactory"factory-method="createMBeanServer"></bean>
</property>
<property name="beans">
<map>
<entry key="MyAgent:name=htmladapter,port=9092">
<bean class="com.sun.jdmk.comm.HtmlAdaptorServer"init-method="start">
<property name="port">
<value>9092</value>
</property>
</bean>
</entry>
<entry key="MyAgent:name=hello">
<ref bean="hello" />
</entry>
</map>
</property>
</bean>
<bean id="hello" class="test.jmx.HelloWorld"/>
</beans>
清单七
TestSpringJmx
publicclass TestSpringJmx {
public static void main(String[] args) {
ApplicationContext ctx = newClassPathXmlApplicationContext(
"jmx-config.xml");
}
}
运行TestSpringJmx
在浏览器中运行http://localhost:9092/
你会看到与上面第一次采用Htmladaptor一样的效果了!从这里你就会看到Spring 的作用了,简单的一个配置文件,和以行程序,就能达到HelloAgent程序一样的效果!
结束语
JDMK5.1为新一代的资源管理提供了丰富的API,你可以借助JDMK5.1提供的API来开发你的程序。