随笔-109  评论-187  文章-25  trackbacks-0

                                 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/). 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 {

       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 来开发你的程序。

 

参考资料

 


 

   文章下载以及源代码

posted on 2006-06-26 11:10 小小程序程序员混口饭吃 阅读(2417) 评论(1)  编辑  收藏 所属分类: java

评论:
# re: jmx入门(图片无法贴上来?在文章最后面附了word文档) 2008-12-23 21:16 | someone
非常感谢  回复  更多评论