随笔-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 小小程序程序员混口饭吃 阅读(2357) 评论(1)  编辑  收藏 所属分类: java

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

只有注册用户登录后才能发表评论。


网站导航: