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來開發你的程序。