?????????????????????
??????
???
JMX
入門(mén)
JMX
越來(lái)越多得出現(xiàn)在各種技術(shù)雜志、以及社區(qū),如
ibm
的
developerworks
和
bea
的
dev2dev
。不僅僅是
SUN
,許多廠商都宣布已經(jīng)或是準(zhǔn)備支持這一技術(shù)。
IBM
、
BEA
、
HP
、
Marcomedia(JRun)
這些大的廠商,而且還有許多小的軟件公司和開(kāi)源項(xiàng)目也都加入了這一行列。為什么
JMX
那么受歡迎,
JMX
到底有那些優(yōu)勢(shì)只得人們?nèi)W(xué)習(xí)和理解,本文從
JMX
的基本架構(gòu)、
hellowold jmx
以及
spring
對(duì)
JMX
的支持講起,希望大家能通過(guò)本文對(duì)
JMX
有個(gè)基礎(chǔ)的認(rèn)識(shí),并能通過(guò)本文為今后學(xué)習(xí)
JMX
打個(gè)基礎(chǔ)
JMX
中的術(shù)語(yǔ):
-
MBean
:是
Managed?Bean
的簡(jiǎn)稱(chēng)。在
JMX
中
MBean
代表一個(gè)被管理的資源實(shí)例,通過(guò)
MBean
暴露一系列方法和屬性,外界可以獲取被管理的資源的狀態(tài)和操縱
MBean
的行為。事實(shí)上,
MBean
就是一個(gè)
Java?Object
,同
JavaBean
模型一樣,外界使用反射來(lái)獲取
Object
的值和調(diào)用
Object
的方法,只是
MBean
提供了更加容易操作的反射的使用。
Mbean
包括
4
種類(lèi)型:標(biāo)準(zhǔn)
MBean
、動(dòng)態(tài)
MBean
、開(kāi)放
MBean
、模型
MBean
。
-
MBeanServer
:
MBeanServer
是
MBean
的容器。
MBeanServer
管理這些
MBean
,并且通過(guò)代理外界對(duì)它們的訪問(wèn)。
MBeanServer
提供了一種注冊(cè)機(jī)制,通過(guò)注冊(cè)
Adaptor
和
Connector
,以及
MBean
到
MBeanServer
,并且通過(guò)代理外界對(duì)它們的訪問(wèn)。外界可以通過(guò)名字來(lái)得到相應(yīng)的
MBean
實(shí)例。
-
JMX?Agent
:
Agent
只是一個(gè)
Java
進(jìn)程,它包括這個(gè)
MBeanServer
和一系列附加的
MbeanService
。當(dāng)然這些
Service
也是通過(guò)
MBean
的形式來(lái)發(fā)布。
-
Protocol?Adapters?and?Connectors
JMX?Agent 通過(guò)各種各樣的 Adapter 和 Connector 來(lái)與外界 (JVM 之外 ) 進(jìn)行通信。同樣外界( JVM 之外)也必須通過(guò)某個(gè) Adapter 和 Connector 來(lái)向 JMX?Agent 發(fā)送管理或控制請(qǐng)求。 Jdmk5.1 中, sun 提供很多 Adaptor 和 Connector 的實(shí)現(xiàn)
??? Adapter 和 Connector 的區(qū)別在于: Adapter 是使用某種協(xié)議 (HTTP 或者 SNMP) 來(lái)與 JMX?Agent 獲得聯(lián)系, Agent 端會(huì)有一個(gè)對(duì)象 (Adapter) 來(lái)處理有關(guān)協(xié)議的細(xì)節(jié)。比如 SNMP?Adapter 和 HTTP?Adapter 。而 Connector 在 Agent 端和 client 端都必須有這樣一個(gè)對(duì)象來(lái)處理相應(yīng)的請(qǐng)求與應(yīng)答。比如 RMI?Connector 。
JMX?Agent 可以帶有任意多個(gè) Adapter ,因此可以使用多種不同的方式訪問(wèn) Agent 。
JMX
基本構(gòu)架:
JMX
分為三層,分別負(fù)責(zé)處理不同的事務(wù)。它們分別是:
-
Instrumentation?
層
? Instrumentation 層主要包括了一系列的接口定義和描述如何開(kāi)發(fā) MBean 的規(guī)范。通常 JMX 所管理的資源有一個(gè)或多個(gè) MBean 組成,因此這個(gè)資源可以是任何由 Java 語(yǔ)言開(kāi)發(fā)的組件,或是一個(gè) JavaWrapper 包裝的其他語(yǔ)言開(kāi)發(fā)的資源。 -
Agent?
層
? Agent 用來(lái)管理相應(yīng)的資源,并且為遠(yuǎn)端用戶(hù)提供訪問(wèn)的接口。 Agent 層構(gòu)建在 Intrumentation 層之上,并且使用管理 Instrumentation 層內(nèi)部的組件。通常 Agent 由一個(gè) MBeanServer 組成。另外 Agent 還提供一個(gè)或多個(gè) Adapter 或 Connector 以供外界的訪問(wèn)。 -
Distributed?
層
Distributed 層關(guān)心 Agent 如何被遠(yuǎn)端用戶(hù)訪問(wèn)的細(xì)節(jié)。它定義了一系列用來(lái)訪問(wèn) Agent 的接口和組件,包括 Adapter 和 Connector 的描述。
?
?
Jmx
三層之間的關(guān)系:
MBean
MBean Serve
r
MBean
HTTP Adaptor
MBean
RMI Adaptor
SNMP Adaptor
Agent
level
Instrumentation
level
Connector
level
JMX
Manager
WEB
Browse
SNMP
Manager
Remote
Manager
???????????????????????????????
???(
圖一)
本圖片來(lái)自
SUN JDMK
的官方文檔
(
圖二)
用另外的一個(gè)圖來(lái)解釋這
3
層之間的關(guān)系
開(kāi)戶(hù)(注冊(cè))
儲(chǔ)蓄用戶(hù)(
MBean
)
開(kāi)戶(hù)(注冊(cè))
銀行
(
MBean
server
)
企業(yè)貸款用戶(hù)
adaptor
connector
企業(yè)貸款
?manager
?????????????????????????????? (圖三)
1 :儲(chǔ)蓄用戶(hù)、企業(yè)貸款用戶(hù)都需要到銀行注冊(cè)開(kāi)戶(hù)
2 :企業(yè)貸款需要通過(guò)其開(kāi)戶(hù),然后從銀行拿到錢(qián)
3 :拿到的錢(qián)是大部分儲(chǔ)蓄用戶(hù)存入的
JMX 的開(kāi)發(fā)過(guò)程也是如此
1 :創(chuàng)建一個(gè) JMXServer
2 :創(chuàng)建 Mbean
3 :把創(chuàng)建的 Mbean 和現(xiàn)成的 Adaptor 注冊(cè)到 JMXServer 上來(lái)
4 :?jiǎn)?dòng) JMXServer
5 : manager 通過(guò) Adaptor 訪問(wèn) Resource ( Mbean )
Hello wold
開(kāi)發(fā)
所需要資源:
1
:
jdk1.4 eclipse ?jdmk5.1(http://www.sun.com/software/jdmk/). spring
2 :從下載的 ZIP 包里面用到: jmx.jar, jmxremote.jar,jdmkrt.jar,
3 :為什么要采用 jmxremote.jar,jdmkrt.jar , sun 提供了一些對(duì) adaptor 以及 connector 供開(kāi)發(fā)者使用。
本文的 helloworld 會(huì)采用 htmladaptor 以及 RmiConnector 的進(jìn)行訪問(wèn),并且用 spring 來(lái)展示 spring 對(duì) JMX 的支持(展示 htmladaptor )。
文件夾結(jié)構(gòu)已經(jīng)會(huì)用到的類(lèi)
?
1 :通過(guò) htmladaptor 對(duì)訪問(wèn),程序具體解釋
?? HelloWorldMBean 是一個(gè) ingerfrace
?? HelloWorld 是 HelloWorldMBean 的實(shí)現(xiàn)
?? HelloAgent 里面創(chuàng)建了一個(gè) MbeanServer ,并且把創(chuàng)建的 Mbean 和 sun 提供的 Adaptor 注冊(cè)在 MbeanServer 上
清單一
HelloWorldMbean
public interface HelloWorldMBean {
?????? public void sayHello();
?????? public void setHello(String hello);
}
清單二
HelloWorld
public class HelloWorld implements HelloWorldMBean {
?????? private String hello;
?????? public HelloWorld() {
????????????? this.hello = "Hello World! I am a Standard MBean";
?????? }
?????? public HelloWorld(String hello) {
????????????? this.hello = hello;
?????? }
?????? public void setHello(String hello) {
????????????? this.hello = hello;
?????? }
?????? public void sayHello() {
????????????? System.out.println(hello);
?????? }
}
清單三
HelloAgent
public class HelloAgent {
?????? private MBeanServer mbs = null;
?????? public HelloAgent() {
????????????? //create a MBeanServer
????????????? mbs = MBeanServerFactory.createMBeanServer("HelloAgent");
????????????? //create an adapter
????????????? HtmlAdaptorServer adapter = new HtmlAdaptorServer();
????????????? //create a MBean
????????????? HelloWorld hw = new HelloWorld("hello boys!");
????????????? ObjectName adapterName = null;
????????????? ObjectName helloWorldName = null;
????????????? try {
???????????????????? adapterName = new ObjectName(
?????????????????????????????????? "HelloAgent:name=htmladapter,port=9092");
???????????????????? //regisetr the adapter to the MBeanServer
???????????????????? mbs.registerMBean(adapter, adapterName);
???????????????????? //declare the port which the adapter user
???????????????????? adapter.setPort(9092);
???????????????????? //start the adapter
???????????????????? adapter.start();
???????????????????? helloWorldName = new ObjectName("HelloAgent:name=helloWorld1");
???????????????????? mbs.registerMBean(hw, helloWorldName);
????????????? } catch (Exception e) {
???????????????????? e.printStackTrace();
????????????? }
?????? }
?????? public static void main(String args[]) {
????????????? //declare the agent and start the adapter
????????????? HelloAgent agent = new HelloAgent();
?????? }
}
必須注意的問(wèn)題
1:MBean 接口的命名,必須遵循 xxxMBean
2:MBean 實(shí)現(xiàn)類(lèi)的命名必須遵循使用 xxx
3:MBean 實(shí)現(xiàn)類(lèi)必須是一個(gè) Concrete class 可以實(shí)例化,并且必須最少有一個(gè)構(gòu)造函數(shù)并且為 public
HtmlAdapter 是 sun JDMK 工具包中提供的 adaptor
運(yùn)行上面的 agent: 在瀏覽器中輸入: http://localhost:9092/
????????????????????? ( 圖五 )
通過(guò)瀏覽器你可以訪問(wèn)注冊(cè)的 helloagent, 并且通過(guò) agent ,可以訪問(wèn)到您注冊(cè)到 MbeanServer 上的 MBean
HelloAgent 下面有有 2 個(gè)資源
?1 : helloworld1 是注冊(cè)上來(lái)的 MBean
?2: htmlAdpter 是注冊(cè)上來(lái)的 adapter
? 現(xiàn)在就可以通過(guò)瀏覽器來(lái)管理 hellowold1 這個(gè) MBean
點(diǎn)擊 name=helloWorld1 就可以進(jìn)來(lái)管理 helloword1 這個(gè) MBean
輸入一個(gè) hello girls , 然后 Apply
那么 Helloword 里面的 hello 變量就成為 hello girls
??????????????????????????? ( 圖六 )
點(diǎn)擊 List of MBean operations ,下面的 sayHello, 就會(huì)發(fā)現(xiàn)控制臺(tái)打印出 say girls
通過(guò)
Adaptor
來(lái)管理
MBean
是不是很簡(jiǎn)單,當(dāng)然我們這里管理的只是一個(gè)
Standerd MBean
,并且是沒(méi)有
notification
的機(jī)制,如果您想深入的學(xué)習(xí),可以去亞馬遜書(shū)店買(mǎi)一本
JMX in Action
這是英文的,國(guó)內(nèi)目前還沒(méi)有譯本。
RMI 的 AGENT 以及通過(guò) RMIConnecterClient 對(duì) MBean 的管理
清單四
RMIAgent
public class RMIAgent {
?????? public static void main(String[] args) {
????????????? MBeanServer mbs = MBeanServerFactory.createMBeanServer("HelloAgent");
????????????? RmiConnectorServer connector = new RmiConnectorServer();
????????????? ObjectName connectorName = null;
????????????? try {
???????????????????? connectorName = new ObjectName("HelloAgent:name=RMIConnector");
???????????????????? mbs.registerMBean(connector, connectorName);
???????????????????? HelloWorld hw = new HelloWorld("hello boys!");
???????????????????? ObjectName helloWorldName = new ObjectName(
?????????????????????????????????? "HelloAgent:name=helloWorld1");
???????????????????? mbs.registerMBean(hw, helloWorldName);
???????????????????? connector.start();
????????????? } catch (Exception e) {
???????????????????? e.printStackTrace();
????????????? }
?????? }
}
清單五
RMIManager?
public class RMIManager {
?????? public static void main(String[] args) {
????????????? RmiConnectorClient client = new RmiConnectorClient();
????????????? RmiConnectorAddress address = new RmiConnectorAddress();
????????????? try {
???????????????????? client.connect(address);
???????????????????? ObjectName helloWorldName = ObjectName
?????????????????????????????????? .getInstance("HelloAgent:name=helloWorld1");
???????????????????? client.invoke(helloWorldName, "sayHello", null, null);
???????????????????? client.setAttribute(helloWorldName, new Attribute("Hello",
?????????????????????????????????? new String("hello girls!")));
???????????????????? client.invoke(helloWorldName, "sayHello", null, null);
????????????? } catch (Exception e) {
???????????????????? e.printStackTrace();
????????????? }
?????? }
}
執(zhí)行 RMIManager 打印出以下結(jié)果
hello boys!
hello girls !
清單六
下面采用 Spring 來(lái)演示 htmladaptor
Rmi-config.xml
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!
DOCTYPE
beans
PUBLIC
"-//SPRING//DTD BEAN//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
public class TestSpringJmx {
?????? public static void main(String[] args) {
????????????? ApplicationContext ctx = new ClassPathXmlApplicationContext(
??????????????????????????? "jmx-config.xml");
?????? }
}
運(yùn)行 TestSpringJmx
在瀏覽器中運(yùn)行 http://localhost:9092/
你會(huì)看到與上面第一次采用 Htmladaptor 一樣的效果了!從這里你就會(huì)看到 Spring 的作用了,簡(jiǎn)單的一個(gè)配置文件,和以行程序,就能達(dá)到 HelloAgent 程序一樣的效果!
結(jié)束語(yǔ)
? JDMK5.1 為新一代的資源管理提供了豐富的 API, 你可以借助 JDMK5.1 提供的 API 來(lái)開(kāi)發(fā)你的程序。
參考資料
- Spring reference ?spring.1.2.4 下載
- Sun jdmk ?and it’s? docs
- BEN G. SULLINS? 和 ? MARK B. WHIPPLE? JMX in Action 一書(shū) ( 英文版 )
- Sun jmx reference document
?
?? 文章下載以及源代碼