?????????????????????
??????
???
JMX
入門
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 Serve
r
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/). spring
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 {
?????? 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();
?????? }
}
必須注意的問題
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 變量就成為 hello girls
??????????????????????????? ( 圖六 )
點擊 List of MBean operations ,下面的 sayHello, 就會發現控制臺打印出 say girls
通過
Adaptor
來管理
MBean
是不是很簡單,當然我們這里管理的只是一個
Standerd MBean
,并且是沒有
notification
的機制,如果您想深入的學習,可以去亞馬遜書店買一本
JMX in Action
這是英文的,國內目前還沒有譯本。
RMI 的 AGENT 以及通過 RMIConnecterClient 對 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();
????????????? }
?????? }
}
執行 RMIManager 打印出以下結果
hello boys!
hello girls !
清單六
下面采用 Spring 來演示 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");
?????? }
}
運行 TestSpringJmx
在瀏覽器中運行 http://localhost:9092/
你會看到與上面第一次采用 Htmladaptor 一樣的效果了!從這里你就會看到 Spring 的作用了,簡單的一個配置文件,和以行程序,就能達到 HelloAgent 程序一樣的效果!
結束語
? JDMK5.1 為新一代的資源管理提供了豐富的 API, 你可以借助 JDMK5.1 提供的 API 來開發你的程序。
參考資料
- Spring reference ?spring.1.2.4 下載
- Sun jdmk ?and it’s? docs
- BEN G. SULLINS? 和 ? MARK B. WHIPPLE? JMX in Action 一書 ( 英文版 )
- Sun jmx reference document
?
?? 文章下載以及源代碼