Chinaunix首页 | 论坛 | 博客
  • 博客访问: 520246
  • 博文数量: 260
  • 博客积分: 10435
  • 博客等级: 上将
  • 技术积分: 1939
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-24 14:50
文章分类

全部博文(260)

文章存档

2011年(22)

2010年(209)

2009年(29)

我的朋友

分类: Java

2010-10-11 11:49:05

JMX技术提供一个简单,标准的方式管理应用程序,设备和服务等资源,一旦这些资源被创建,安装和实现,你能利用JMX的动态特性来监控和管理它们。同时你也可以用JMX来监控和管理JVM
JMX技术基于以下两个JSR开发:
  * JSR 3, Java Management Extensions Instrumentation and Agent Specification
  * JSR 160, Java Management Extensions Remote API 

JMX规范,定义了一个架构、设计模式、APIs和服务,为应用程序和网络提供管理和监控。

    使用JMX,一个给定的资源,如可管理的Beans或者MBeans,可以被一个或者更多个Java对象操作。这些MBeans注册在一个核心的管理对象 的Server上。如MBean Server,它当作一个管理的agent,能运行在大部分可用Java激活的设备上。

 使用JMX agents管理资源操作必须依照规范。一个JMX agent有一个MBean Server组成,这个MBean Server,提供给MBeans 注册和一些列操作Mbeans服务,这样JMX agents直接控制资源,使得能远程控制应用程序。

    这种方式能使得被操作的资源能彻底的独立于管理的底层结构,不产生任何依赖。资源可以不关心它们的管理程序如何实现。

    JMX技术定义了标准的connectors(JMX connectors),使你能远程访问JMX agents,JMX使用不同的协议提供相同的管理接口,所以管理程序可以透明的管理资源,不用考虑使用哪种通讯协议。JMX agents也可用于支持JMX agents但与JMX规范不一致的系统和应用。

下面的图片可以看出大概结构:

为何使用JMX

 JMX技术能提供给所有工业行业的Java开发者一个灵活的mbeans去操作Java代码,创建灵活的Java代理,实现分布式的管理中间件和管理,而且能平稳的集成到已经存在的管理和监控系统中去。

 1  JMX使得Java应用可被管理只需要很少的投入:
一个JMX agent能运行在大部分Java激活的设备上,因此Java应用是否可被管理与原来的设计基本没有冲突。Java应用只需要简单的嵌入一个管理对象的 Server,并在其上注册一个或多个管理Beans(MBeans)在Server上,使Server上一些功能可用。这就是从管理的基层结构获得的益 处。

2  JMX提供一个标准的方式管理Java编写的应用,系统和网络,例如:JavaEE 5的应用服务器遵循JMX架构,因此可以使用JMX技术管理。

3  JMX可以使用于JVM。你可以轻易的启动一个JMX agent 访问这内置的JVM,因此可以远程的管理和监控JVM

4 JMX提供一个可升级的,动态管理的构架。每个JMX agent服务都是独立的模块,可以根据需求,可插入管理agent中去。这种基于构件的方式意味着JMX解决方案可以在small-footprint 设备和大的 telecommunications之间切换。JMX规范提供一些核心的agent服务,另外的服务可以在管理的底层结构下自行开发,并且能动态加载, 移除和修改。

5  JMX技术利用了以前存在的标准Java技术,例如JNDI

6  使用NetBeans IDE5.0的JMX模块开发JMX应用已经非常容易了。你可以从NetBeans升级重新获得这JMX模块

7 JMX可以容易的集成已经存在的管理方案和技术。例如:JMX agents可以通过HTML浏览器管理,JMX APIs是开放的接口,任何管理系统卖主都可以利用。JMX方案可以使用Jini网络技术和Service Location Protocol (SLP)来查询服务。






Web应用系统总算开发了,接下来该如何让客户(Web应用系统的管理员)轻松管理我的一堆配置文件,或者如何实现动态修改系统运行属性,同时又让客户不 需要过多的了解配置文件的内容就能够实现这些管理呢?这是许多刚刚结束Web应用系统前期开发的系统分析人员需要面临的问题。又或者说我想对早已完成 Web应用系统进行有效的资源管理,希望再添加管理功能的同时,对原有的代码不需要做过多的修改,换句话说就是管理系统与被管理的应用系统做到很好的隔 离。JMX的管理框架(图1)为你很好的解决了这些问题。



  JMX(Java Management Extensions)是来管理网络,设备,应用程序等资源,它描述了一个可扩展的管理体系结构,并且提供了JMX API和一些欲定义的java管理服务。在撰写本文时,JMX规范最新版本为v1.2( /communityprocess/final/jsr003/index3.html),JMX参考实现的最新版本为v1.2.1(http: //java.sun.com/products/JavaManagement/)。JMX推出后,一些大型的项目就立即采用了基于JMX的实现框架, 例如Jakarta tomcat和JBoss,这从分说明JMX的可行性和良好的特性。

  对于Web应用的管理往往是比较麻烦的,例如客户手动的修改配置文件,开启数据库监控程序等等,如果要动态修改数据库访问方案或者监控用户数,动态修 改日志级别会更加麻烦,并且可能把系统的结构弄得凌乱,造成结构不良的恶果,更别说可扩展性了。JMX的分层结构以及高度的组件化,通过将各种资源封装成 MBean的方式,让我们可以很低成本的实现对现有Web应用的扩展性很强的管理方案。

  本文以Tomcat作为Web服务器为例,详细的介绍如何使用JMX建立对Web应用的管理。对于JMX的概念性的东西、体系结构以及使用规范已经有 不少的相关文档,为了能够更好的理解本文,在阅读本文时请先参阅这些文档,本文的笔墨将着重在应用和实现上。下图(图2)为JMX的基本框架图(见JMX 规范),,目的是给大家理解本文提供方便。


一、创建Web应用的管理系统

  对Web应用构建一个基于JMX的管理系统,我们需要做的事情有哪些呢?

  针对每一个需要管理的资源创建一个MBean的实例,这是JMX框架所要求的,有两种类型的实例可供选择,一种是直接管理资源的MBean,一种通过调用资源实例进行管理的MBean。

  编写一个MBean描述文件,并描述每一个MBean,选择基于XML的MBean描述文件是一个不错的决定。

  通过读MBean描述文件,生成MBeanInfo,从而生成一个个MBean。

  将需要进行管理的MBean注册到MBean Server当中。

  编写客户端代码,选择Web的方式进行客户端的编码比较Web应用的风格,也比较容易实现。

  那么一个基于JMX的Web应用的管理框架已经成形,图3是它的基本结构图,虚线部分为基于JMX的管理系统。接下来我们按照步骤实现整个管理系统。



  二、获得MBeanServer的实例

  有两种方案获得MBeanServer的实例。

  1、通过获得Web服务器的MBeanServer的实例,这样做的好处是通过该MBeanServer对本身,甚至可以实现对Web服务器的自身的 一些管理。Tomcat的管理框架也是建立JMX的基础上,它使用的JMX的实现是MX4J,这是一个非常优秀的JMX开源项目,在 tomcat4.1.27中,MBeanServer的实例存放与属性名为"org.apache.catalina.MBeanServer"的 application变量(Web应用中变量的几种范围:page,request,session,application)中,因此servlet 中获得MBeanServer实例的办法:
  server = (MBeanServer) getServletContext().getAttribute("org.apache.catalina.MBeanServer"); 
  如果通过这种方式,你获得的server为null,这说明你必须还要完成下面的工作,使你能够有权限获得系统的 MBeanServer,tomcat才会将MBeanServer的实例存放在web应用程序下属性 名"org.apache.catalina.MBeanServer"的系统变量中。

  找到tomcat下conf目录,修改server.xml文件。修改Web应用的context元素,添加上privileged="true"这一项属性即可,例如:
  <Context path="/myapp" docBase="c:/web/" debug="9" privileged="true" reloadable="true" crossContext="true"/> 
  2、通过JMX API中MBeanServerFactory类的createMbeanServer()的方法创建MBeanServer的实例,这样做得好处的使 JMX的实现与Web服务器无关,使代码的移植性更强。在创建完MBeanServer以后,为了让能够在管理系统中很方便的获得该 MBeanServer的引用,可将其置入application变量中(推荐),或者使用singleton设计模式的方法创建和获得。

  使用JMX API创建MBean Server的代码如下:
MBeanServer server = MBeanServerFactory.createMBeanServer(); 

  究竟采取何种方案获得MBeanServer并不十分重要,可以考虑实现的方便进行选择。

  三、创建MBean

  为了能够管理Web应用的资源,首先要使资源能够被管理,按照JMX规范的要求,我们将资源封装成MBean,实际上也就是为Web应用添加可管理性。

  获得MBeanServer的实例以后,就可以编写自己的MBean了,根据JMX的规范,MBean有标准的和动态的两种主要类型,这里就不赘述 了,具体可以参看JMX的规范(http://)。有两种用于特殊用途的动态 MBeans:模型MBean和开放MBean。模型 MBean (Modle MBean)提供了"现成的"MBean 实现,您可以使用它来快速地利用任何 JMX 可管理资源。它是预制的、通用的和动态的 MBean 类,并且提供了参考实现,已经包含了所有必要缺省行为的实现 - 允许您在运行时添加或覆盖需要定制的那些实现。这使得基于 Java 的、非工具化的资源能够在运行时提供保证兼容的 MBean 虚包,使它们能够通过 JMX 体系结构进行管理。

  在Web应用中,资源是多元化,有运行实例,静态文件,甚至是设备或者是硬件状态,那么我们把这些资源可以分为两类,一些资源需要进行动态的管理监控 (如登陆用户数,数据库连接监控,即时日志等),一些则是静态资源,只需要进行静态的管理(系统配置文件,日志级别等),要管理这些不同类型的资源,这就 要求MBean一方面能够直接调用运行实例提供的接口进,另一方面又希望MBean自身能够提供静态资源的管理,模型MBean能够很好的满足这样的要 求,并且对于新增需要管理的资源,提供了很好的灵活性和可扩展性,因此推荐模型MBean作为Web应用首选。当然具体采用何种类型的MBean,需要结 合不同的应用,或者多种类型的MBean相结合使用。顺便提一点,采用不同类型的MBean,对于管理客户端是透明的,也就是说客户端使用一致的访问方法 来访问MBean的属性和方法,这也是JMX的一个优点。

  为了更好的观察如何实现对静态资源和动态资源的管理,本文编写了两个MBean,分别实现对数据库连接属性实现静态和动态的管理。静态管理的 MBean的目的是实现对数据库配置文件修改,这样当Web应用重启后,会使用新的数据库配置,我们采用MBean的提供对资源的直接操作进行实现。动态 管理的MBean目的是对已经实例化的数据库连接对象的属性进行修改,这样在不重新启动Web应用的情况下,改变数据库连接。

  1、实现管理配置文件的MBean。

  JDBCConfig是一个Model MBean,它的作用是对config.properties文件封装成MBean,该MBean包括四个属性及其相关的getter和setter和一 个save方法,其中save方法的作用是属性存入配置文件,从而实现了通过MBean直接对配置文件进行操作。这个例子中的MBean继承了 BaseModelMBean类,该类实现了javax.management.ModelMBean接口,我们可以在commons- modeler.jar中找到BaseModelMBean类,commons-modeler.jar是tomcat4.x中使用的一个开放源码的包。

import javax.management.MBeanException; import javax.management.RuntimeOperationsException; import org.apache.commons.modeler.BaseModelMBean; import java.io.*; import java.util.Properties; public class JDBCConfigMBean extends BaseModelMBean { private String driver; private String username; private String password; private String dburl; private static final String CONFIG_FILEPATH = "c:\\myweb\\conf\\config.properties"; /////////////////////////////////////////////////////////////////// //constructor /////////////////////////////////////////////////////////////////// public JDBCConfig() throws MBeanException, RuntimeOperationsException { super(); init(); } private void init() { InputStream in = null; try { Properties prop = new Properties(); in = new BufferedInputStream( new FileInputStream(CONFIG_FILEPATH)); prop.load(in); driver = prop.getProperty("driver"); dburl = prop.getProperty("dburl"); username = prop.getProperty("username"); password = prop.getProperty("password"); in.close(); } catch (Exception e) { try { if (in != null) in.close(); } catch (IOException e1) { e1.printStackTrace(); } e.printStackTrace(); } } /////////////////////////////////////////////////////////////////// //getter and setter /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// //public method /////////////////////////////////////////////////////////////////// public String save() { OutputStream out = null; try { out = new BufferedOutputStream(new FileOutputStream(CONFIG_FILEPATH)); Properties prop = new Properties(); prop.setProperty("driver", driver); prop.setProperty("dburl", dburl); prop.setProperty("username", username); prop.setProperty("password", password); prop.store(out, "---jdbc config---"); out.close(); return "save success!"; } catch (Exception e) { try { if (out != null) out.close(); } catch (IOException e1) { e1.printStackTrace(); } e.printStackTrace(); return "save error!"; } } }


2、实现修改运行实例的属性。

  上面的例子是对静态资源的修改,如果需要对正在运行的类实例进行动态修改,Model MBean同样提供了很好的方法,在javax.management.ModelMBean的API中有个setManagedResourced方 法,这个方法的作用是将正在运行的类实例置入Model MBean,实际上所要做的也就这么多。当需要对改变实例属性的时候,只需要调用MBean的setAttribute的方法即可,MBean将会通过反 射调用该实例对应的属性设置方法,就是这么简单。但是许多人喜欢直接从代码了解过程,因此我将如何实现动态修改实例的属性代码也写出来。同样以JDBC为 例,这里假设系统已经有了一个使用JDBC的数据库连接,现在需要改变JDBC的属性,并建立新的连接,这一切都在不重启Web应用系统的情况下完成。

  第一段代码是Web应用使用的数据库连接类,它提供一个获得数据库连接,和测试连接属性的两个方法,以及相关的属性。当Web应用启动时,该类将会实例化,我们暂且把这个实例叫资源实例。 package com.myApp.db; import java.sql.Connection; import java.sql.SQLException; public class DBAccess { private String driver; private String username; private String password; private String dburl; public Connection getConnection() { ...... } public static boolean testConnection(String driver,String username, String password,String dburl) { } /////////////////////////////////////////////////////////////////// //getter and setter /////////////////////////////////////////////////////////////////// }


  第二段代码是一个Model MBean类,和前面提到的第一个Model MBean一样,继承了BaseModelMBean,不同的是它将拥有Web应用运行时期资源实例的引用,因为所有的属性和方法都在所引用的资源实例 中,父类BaseModelMBean完成了通过反射调用该资源实例对应的属性设置方法,所以这个类的编写相当简单,我们可以在里面完成其他一些相关的方 法。

package com.myApp.db; import org.apache.commons.modeler.BaseModelMBean; import javax.management.MBeanException; import javax.management.RuntimeOperationsException; public class ResInstanceMBean extends BaseModelMBean { public ResInstanceMBean () throws MBeanException, RuntimeOperationsException { super(); } /** other operations **/ ..... }

  第三段代码是如何实现管理数据库连接类的运行实例。

/**Web应用运行初期创建的数据库连接**/ DBAccess dbAccess = new DBAccess(); dbAccess.setDriver(); dbAccess.setPassword(); dbAccess.setUsername(); dbAccess.setDburl(); ...... /** 创建并注册管理数据库的MBean //创建mbean ResInstanceMBean mbean= new ResInstanceMBean(); //设置MBeanInfo,这是必须的 mbean.setModelMBeanInfo(createMBeanInfo()); //设置MBean所管理的资源实例,instance为数据库连接的实例, //"objectReference"是必须的,否则将无法将资源实例设置到MBean中,记住就行了 DBAccess instance = getDBAccess(); mbean.setManagedResource(instance, "objectReference"); //注册mbean到MBean Server中 MBeanServer serv = getMBeanServer(); ObjectName oname = createObjectName(mbean); serv.registerMBean(mbean, oname);

  四、创建MBean描述文件

  在上面第三段代码中,我们可以看到,要将MBean注册到MBean Server中必须先创建MBeanInfo,MBean的setModelMBeanInfo()用来将MBeanInfo设置到MBean中。为了能 够灵活的获得MBean的信息,从而将MBean注册到MBeanServer,在O'Reilly出版的"java enterprise的最佳实践"里提到,采用XML文件对MBean描述是一种非常不错的选择方案,并且提供了一个XML描述范例,因此本文也推荐在管 理Web应用也采用使用MBean描述文件的方法。实际上无论tomcat4.X,还是JBOSS,都采用使用MBean描述文件的方式创建MBean, 下面提供了一个Tomcat4.x里面的MBean描述文件方案,并用该方案描述了上述提到的两个数据库连接管理的MBean。Tomcat提供了读取该 描述文件的办法,具体可以参看Tomcat提供的帮助文档--如何使用MBean descriptor ( " howto.html")。

<mbean-list>
<mbean name="JDBCConfigMBean"
className="com.myApp.jmx.JDBCConfigMBean"
description="the object to access database"
domain="myapp">
<attribute name="driver"
description="Jdbc driver name"
type="java.lang.String"
writeable="false"/>
<attribute name="dburl"
description="database url"
type="java.lang.String"/>
<attribute name="username"
description="Database user name"
type="java.lang.String"/>
<attribute name="password"
description="vthe user name's password"
type="java.lang.String"/>
<operation name="save"
description="save the configuration"
impact="ACTION"
returnType="java.lang.String">
</operation>
</mbean>
<mbean name="DBAccess"
className="com.myApp.jmx.ResInstanceMBean"
description="the object to access database"
domain="myapp"
type="com.myApp.db.DBAccess">
<attribute name="driver"
description="Jdbc driver name"
type="java.lang.String"
writeable="false"/>
<attribute name="dburl"
description="database url"
type="java.lang.String"/>
<attribute name="username"
description="Database user name"
type="java.lang.String"/>
<attribute name="password"
description="vthe user name's password"
type="java.lang.String"/>
<operation name="testConnection"
description="test configure attribute"
impact="ACTION"
returnType="java.lang.String">
<parameter name="driver"
description="Jdbc driver name for test"
type="java.lang.String"/>
<parameter name="username"
description="Database user name for test"
type="java.lang.String"/>
<parameter name="password"
description="the user name's password for test"
type="java.lang.String"/>
<parameter name="dburl"
description="database url for test"
type="java.lang.String"/>
</operation>
</mbean>
</mbean-list>
  五、注册MBean

  在对MBean注册前,必须得到MBean的描述信息,并且保存在MBeanInfo的实例中,否则是无法将MBean注册到MBean Server当中的,通过MBean描述文件,获得各种类型MBean的描述信息是一件非常简单的事情,而这些正是创建MBean所需要的,这样做的优点 在于不需要通过编写代码,只需要修改描述文件,就可以添加新的MBean,注册的代码实际上我们之前的代码已经列出。在MBean注册时必须指定对应的 ObjectName,ObjectName相当于MBean在MBean Server中的唯一名字,它的格式为:"domain:key1=value1,key2=value2...",可根据系统的要求定义一套命名的规 则。
//注册mbean到MBean Server中 MBeanServer serv = getMBeanServer(); ObjectName oname = createObjectName(mbean); serv.registerMBean(mbean, oname); 
  六、编写管理框架的客户端

  我们已经完成了服务器端MBean的注册工作,接下来是如何让用户能够使用这些MBean管理资源。虽然JMX的参考实现中提供了 HTMLAdapter,使用户能够通过浏览器使用MBean。但是提供的界面并不是那么友好可亲,一向苛刻的客户对这绝对不会满意的。因此,编写一些简 洁的访问MBean页面还是有必要的。如何通过java访问MBean,可以参阅JMX的资料,这些资料非常多。

  根据上面的介绍,如果要增加对Web应用的管理功能或管理系统,基于JMX的管理框架绝对是一个非常明智的选择。



一、JMX简介
    什么是JMX?在一篇网文中是这样说的:"JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服 务实现管理",这句话我现在看着还是不知所云,云里雾里。
    我们还是从JMX能给我们提供什么好处入手来理解吧。举一个应用实例:在一个系统中常常会有一些配置信息,比如服务的IP地址,端口号什么的,那么如何来写这些代码呢?
   1. 程序初哥一般是写死在程序里,到要改变时就去改程序,然后再编译发布;
   2. 程序熟手则一般把这些信息写在一个配置文件里(JAVA一般都是*.properties文件),到要改变时只要改配置文件,但还是重新启动系统,以便读取配置文件里的新值;
   3. 程序好手则会写一个段代码,把配置值缓存起来,系统在读值的时候,先看看配置文件有没有更动。如有更改则重读一遍,否则从缓存里读取值
   4. 程序高手则懂得取物为我所用,用JMX!把配置属性集中在一个类,然后写一个叫MBean的东东,再配置一下就轻松搞定了。而且JMX自动提供了一个WEB页面来给你来改变这些配置信息。

二、准备工作
  JMX是一份规范,SUN依据这个规范在JDK(1.3、 1.4、5.0)提供了JMX接口。而根据这个接口的实现则 有很多种,比如Weblogic的JMX实现、MX4J、JBoss的JMX实现。在SUN自己也实现了一份,不过在JDK1.4之前,这件JMX实现 (一些JAR包)是可选的,你得去它的网站上下载。JDK5.0则内嵌了进来,安装JDK5.0就可以开发基于JMX的代码了。
但JDK5.0并非包含所有SUN的关于JMX的代码,有一些工具类是排除在JDK5.0之外的。下面根据所使用的JDK版本情况,谈一谈开发环境的准备。
1、JDK1.3、1.4
去SUN网站下载SUN的JMX实现,共两个ZIP文件,下载网址:。
(1)jmx-1_2_1-ri.zip
     解压后的lib目录包含:jmxri.jar、jmxtools.jar
(2)jmx_remote-1_0_1_03-ri.zip
     解压后的lib目录包含:jmxremote.jar、jmxremote_optional.jar、rmissl.jar
    如果在DOS下用命令行开发,则把这五个JAR包加入到classpath系统变量中。如果你用Eclipse开发,则把JAR包加  入到项目属性的Libratries(库)引用中。
2、JDK5.0
   JDK5.0的jre\lib\rt.jar已经包含了jmxri.jar、 jmxremote.jar、rmissl.jar三个包的代码。如果你用到jmxtools.jar、jmxremote_optional.jar的 类,则需要将这两个类加入到classpath或 Eclipse的项目库引用中。
3、我使用的开发环境:JDK5.0 + Eclipse3.2。
   注:因为用到jmxtools.jar中的HtmlAdaptorServer类,所以将此包加入到项目库引用中。jmxremote_optional.jar暂时不用到,不管它。

三、HelloWorld实例
  
1、Hello是一个需要被管理的类(普通类) 
 
  1. /** 
  2.  * @author ChenGang 2005-12-3 
  3.  */  
  4. public class Hello implements HelloMBean {  
  5.     private String name;  
  6.     public String getName() {  
  7.         return name;  
  8.     }  
  9.     public void setName(String name) {  
  10.         this.name = name;  
  11.     }  
  12.     public void printHello() {  
  13.         System.out.println("Hello World, " + name);  
  14.     }  
  15.     public void printHello(String whoName) {  
  16.         System.out.println("Hello , " + whoName);  
  17.     }  
  18. }                   
  

   2、要管理Hello则必须创建一个相应MBean,如下:  
  1. /** 
  2.  * @author ChenGang 2005-12-3 
  3.  */  
  4. public interface HelloMBean {  
  5.     public String getName();  
  6.     public void setName(String name);  
  7.     public void printHello();  
  8.     public void printHello(String whoName);  
  9. }   
说明:包含在MBean中方法都将是可以被管理的。MBean起名是有规范的,就是原类名后加上MBean字样。  

   3、创建一个Agent类
 
  1. import javax.management.MBeanServer;  
  2. import javax.management.MBeanServerFactory;  
  3. import javax.management.ObjectName;  
  4. import com.sun.jdmk.comm.HtmlAdaptorServer;  
  5.   
  6. public class HelloAgent {  
  7.   
  8.     public static void main(String[] args) throws Exception {  
  9.         MBeanServer server = MBeanServerFactory.createMBeanServer();  
  10.   
  11.         ObjectName helloName = new ObjectName("chengang:name=HelloWorld");  
  12.         server.registerMBean(new Hello(), helloName);  
  13.   
  14.         ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");  
  15.         HtmlAdaptorServer adapter = new HtmlAdaptorServer();  
  16.         server.registerMBean(adapter, adapterName);  
  17.   
  18.         adapter.start();  
  19.         System.out.println("start.....");  
  20.   
  21.     }  
  22. }   
说明:
    * 先创建了一个MBeanServer,用来做MBean的容器
    * 将Hello这个类注入到MBeanServer中,注入需要创建一个ObjectName类
    * 创建一个AdaptorServer,这个类将决定MBean的管理界面,这里用最普通的Html型界面。AdaptorServer其实也是一个MBean。
    * chengang:name=HelloWorld的名字是有一定规则的,格式为:“域名:name=MBean名称”,域名和MBean名称都可以任意取。

   4、运行HelloAgent,然后打开网页:单击“name=HelloWorld”链接进入

五、总结
在实际系统中我们可以把name变成决定数库链接池的变量,这样我就可以对系统的运行参数进行实现的监控和配置(管理)。而且也

可以对一些方法(如printHello)进行远程调用了


一、JMX简介

  JMX是一种JAVA的正式规范,它主要目的是让程序且有被管理的功能,那么怎么理解所谓的“被管理”呢?试想你开发了一个软件(如WEB网 站),它是在24小时不简断运行的,那么你可能会想要“监控”这个软件的运行情况,比如收到了多少数据,有多少人登录等等。或者你又想“配置”这个软件, 比如现在访问人数比较多,你想把数据连接池设置得大一些。

  当然,你也许会专门为这些管理来开发软件,但如果你借助JMX,则会发现创建这样的管理程序是如此简单。因为你无需为管理程序来开发界面,已经 有通用的JMX管理软件,如MC4J,或者是用一般都附带提供的HTML网页来管理,你要做的仅仅是将自己要被管理和监控类的按照JMX规范修改一下即 可。

  中间件软件WebLogic的管理页面就是基于JMX开发的,而JBoss则整个系统都基于JMX构架。下面将JMX的一些概念,从JMX规范转帖如下:

二、JMX构架中的各层及相关的组件

  1. 工具层(Instrumentation Level)
        (a) MBeans(标准的,动态的,开放的和模型MBeans)
        (b) 通知模型:Notification、NotificationListener等类
        (c) MBean元数据类:Attribute、Opreator等类
  2. 代理层(Agent Level)
        (a) MBean Server
        (b) 代理服务。如前一篇的HtmlAdaptorServer等。

 

  MBean中有getter和setter的就是属性,如前一篇的Hello类中Name。如果只有getter则表示该属性只读。一共有四种MBean,如下:

  1. 标准MBeans(Standard MBeans)设计和实现是最简单的,这类MBean使用自己的方法名作为管理接口;
  2. 动态MBeans(Dynamic MBeans)必须实现一个指定的接口,由于动态MBeans在运行期间暴露它们的管理接口,因此更为灵活;
  3. 开放MBeans(Open MBeans)属于动态MBeans,这类MBean依靠基础数据类型来实现通用管理,并为友情用户进行自我声明;
  4. 模型MBeans(Model MBeans)同样也是动态MBeans,这类MBeans是完全可配置的,在运行期间进行自我声明;它们为资源动态工具提供一个一般性的,有默认行为的MBeans类。
  在前一篇中的Hello、HelloMBean就是一个标准MBeans(Standard MBeans)。后面接下来的几篇,我们会继续介绍其他几种MBean。



核心提示:JMX(Java Management Extensions),顾名思义,是Java管理方案的扩展。JMX所管理的是能被Java抽象的各类应用、系统和网络,所扩展的是相应的管理和监控方 案,并使之模式化和标准化。 JMX是GlassFish整个管理架构的基

JMX(Java Management Extensions),顾名思义,是Java管理方案的扩展。JMX所管理的是能被Java抽象的各类应用、系统和网络,所扩展的是相应的管理和监控方案,并使之模式化和标准化。

JMX是GlassFish整个管理架构的基础。AMX是GlassFish所特有的对JMX应用的扩展,它使得在GlassFish上开发JMX应用时更加面向对象、更加简单。

本章将首先介绍JMX的背景、基本概念和用法,接着将介绍JMX技术在Java EE环境下的应用,然后将说明GlassFish对JMX技术的重要扩展(AMX),最后将说明如何在GlassFish中开发自己的MBean。

本章重点:

l   JMX的基本概念

l   Java EE的JMX应用

l   GlassFish对JMX的扩展和实现

15.1  JMX概述

15.1.1  JMX的背景

JMX技术作为Java管理和监控的标准接口在Java SE 5.0正式被发布出来。现阶段,围绕JMX的主要Java标准Java Specification Requests(JSR)有3个:

l   JSR-3,Java Management Extensions Instrumentation and Agent Specification

l   JSR-160,Java Management Extensions Remote API

l   JSR-77,Java 2 Platform,Enterprise Edition Management Specification

JSR-3和JSR-160都是针对Java SE平台,JSR-3是JMX的标准规范,JSR-160是JMX远程接口的规范。这两个标准将会在下个Java版本Mustang中被合并成JSR-255,具体见图15-1。

图15-1  JMX规范的演变

JSR-77针对Java EE平台,是关于企业应用的管理和监控的进一步的JMX标准。

JMX的各个相关标准定义了标准的管理模型和管理接口,为管理应用的实现提供了方便。典型的JMX管理应用包括:

l   配置查询及更改。

l   各类统计。

l   状态通知。

15.1.2  选择JMX的理由

JMX技术 已被业界广泛地使用,Sun的Sun Java System Application Server、BEA的Weblogic、IBM的Websphere等主流的Java应用服务器都相继采用和支持这个标准。JMX其实并不是什么新发明 的技术,而是对已有的几类Java技术的归纳综合。JMX被迅速广泛地采用,说明这种归纳综合迎合了实际的需求。应用JMX技术所带来的好处归纳如下:

l   以标准的方式管理Java应用、系统和网络。

l   使开发简便,借鉴并沿用了成熟简单的Java Bean的开发模式。

l   松耦合的组件开发实现了系统的可插拔性,降低了移植和维护成本。

l   可实现远程对系统的监控和管理,其中包括了系统底层的JVM。

l   对原有应用改动小,可方便地集成管理系统。



15.3  JMX整合实例

15.3.1  运用JMX技术管理Java样例ArcTest

ArcTest 是一个JDK从1.02起就附带的经典样例。ArcTest是用AWT写成的Applet。它完成的功能是根据设定的起始角度和偏移角度,画出填充或非填 充的扇形,如图15-7所示。下面将应用JMX技术对ArcTest进行改造,并对其用JMX方式管理。另可参见光盘中位于chapter15/ex1的 项目。

图15-7  Java样例ArcTest

【例15.4】应用JMX技术改造ArcTest。

用NetBeans IDE打开例程jmx_legacy,可以看到其目录结构如图15-8所示。

图15-8  例程jmx_legacy的结构

其中:

ArcTest.java是原先的ArcTest例子。

ArcTestJmx.java和ArcTestJmxMBean.java是MBean的实现。

ArcTestJmx_Agent.java实现了JMX代理。

ArcTestJmx_Manage.java实现了分布式管理应用。

可以看到,我们对原有代码未做任何改动,而且只写了很少的代码,就使这个应用的变成一个可管理的应用(具体分析参见以下各小节)。

说明:NetBeans IDE提供有JMX插件,借助这个插件可以自动创建JMX的MBean、管理应用和代理。这个插件可以通过NetBeans的Update Center获得。

15.3.2  MBean的实现

MBean的实现主要通过ArcTestJmxMBean.java和ArcTestJmx.java来完成。其中ArcTestJmx.java定义了MBean的管理接口,ArcTestJmxMBean.java具体实现了MBean的管理接口:

import java.awt.Frame;

public class ArcTestJmx implements ArcTestJmxMBean {

    ArcTest arcTest;

    public ArcTestJmx(ArcTest arcTest){

        this.arcTest = arcTest;

    }

   

    /**

     * 属性: endangle

     */

    private int endAngle;

   

    /**

     * 属性: startangle

     */

    private int startAngle;

   

    //提供默认的构造函数

    public ArcTestJmx() {

        this(new ArcTest());

    }

   

    /**

     * 读MBean的属性endAngle

     */

    public int getEndAngle() {

        return endAngle;

    }

   

    /**

     * 写MBean的属性endAngle

     */

    public void setEndAngle(int value) {

        endAngle = value;

        arcTest.controls.e.setText(value+"");

        arcTest.controls.canvas.endAngle =value;

        arcTest.controls.repaint();       

    }

   

    /**

     *  读MBean的属性startAngle

     */

    public int getStartAngle() {

        return startAngle;

    }

   

    /**

     * 写MBean的属性startAngle

     */

    public void setStartAngle(int value) {

        startAngle = value;

        arcTest.controls.s.setText(value+"");

        arcTest.controls.canvas.startAngle = value;

        arcTest.controls.repaint();       

    }

   

    /**

     * MBean的方法,初始化

     */

    public void start(){

        Frame f = new Frame("ArcTest");          

        arcTest.init();

        arcTest.start();       

        f.add("Center", arcTest);

        f.resize(300, 300);

        f.show();

    }

   

    /**

     * MBean的方法,以不填充的方式画出扇形

     */

    public void draw() {

        arcTest.controls.canvas.filled= false;

        arcTest.controls.repaint();      

    }

   

    /**

     * MBean的方法,以填充的方式画出扇形

     */

    public void fill() {

        arcTest.controls.canvas.filled= true;

        arcTest.controls.repaint();        

    }   

}

15.3.3  JMX代理的实现

ArcTestJMXAgent实现了JMX代理,它完成的主要功能是注册MBean。

相关代码如下:

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;

import javax.management.ObjectName;

import javax.management.remote.JMXConnectorServer;

import javax.management.remote.JMXConnectorServerFactory;

import javax.management.remote.JMXServiceURL;

/**

 * JMX agent类。启动MBean服务器,注册MBean

 */

public class ArcTestJMXAgent {

    // 单一(Singleton)Agent的实例

    private static ArcTestJMXAgent singleton;

    public static void main(String[] args) throws Exception {

        //得到MBean服务器

        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();       

       

        //注册MBean

        ArcTestJmx MBean = new ArcTestJmx();

        ObjectName MBeanName = new ObjectName(":type=ArcTestJmx");

        //注册Mbesan,取名为ArcTestJMX

        mbs.registerMBean(MBean, MBeanName);

       

        //启动连接服务

        //指定使用的协议和对外开发的端口,这里使用默认的RMI协议

        JMXServiceURL url = new JMXServiceURL(

                "service:jmx:rmi:///jndi/rmi://localhost:9999/server");

        JMXConnectorServer connect_server =

                JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);

        System.out.println("\n 启动RMI连接服务");

        connect_server.start();

        System.out.println("JMX Agent已准备好接受请求");

        Thread.sleep(Long.MAX_VALUE);

    }

   

    /**

     * 返回agent的唯一实例

     */

public synchronized static ArcTestJMXAgent getDefault() throws Exception

{

        if(singleton == null) {

            singleton = new ArcTestJMXAgent();

        }

        return singleton;

    }

}

推荐使用默认域名。如果ObjectName未指定域名,则默认为默认域名。

15.3.4  运行实例

启动RMI服务,在命令行执行:

rmiregistry 9999

在NetBeans IDE中,先运行代理ArcTestJmx_Agent.class,提示如下:

启动RMI连接服务

JMX Agent已准备好接受请求

这时MBean服务器已经启动,装载并注册了 MBean:type=ArcTestJmx,并且在端口9999等待访问。先通过通用的JConsole来访问,启动JConsole,在 Advanced选项卡的JMX URLl栏中输入:service:jmx:rmi:///jndi/rmi://localhost:9999/server。

可以看到,ArcTestJmx已经注册在默认的域DefaultDomain下,如图15-9所示。

图15-9  通过JConsole看到的管理应用

再运行管理应用 ArcTestJmx_Manage.class,可以选择直接运行光盘中chapter15/ex1的项目。其实与JConsole一 样,ArcTestJmx_Manage也是个JMX管理应用程序。这个管理应用的任务很简单,就是启动ArcTest,将起始角度赋值为30,再用填充 画法重画。运行后可以看到如图15-10所示的效果。

图15-10  ArcTest的管理应用实现的效果

这个效果没有通过任何手工的界面操作,完全是通过编 程来实现的。相应地修改JMXServiceURL,在任何能访问本机的机器上运行管理应用ArcTestJmx_Manage,都可达到同样的效果。这 说明ArcTest已经可以被管理应用ArcTestJmx_Manage远程地管理起来。

15.3.5  分布式管理应用的实现

ArcTestJMX_Manage的完整代码如下:

import javax.management.Attribute;

import javax.management.MBeanServerConnection;

import javax.management.ObjectName;

import javax.management.remote.JMXConnector;

import javax.management.remote.JMXConnectorFactory;

import javax.management.remote.JMXServiceURL;

/**

 * JMX管理应用

 */

public class ArcTestJMX_Manage {

   

    //JMX连接器

    private JMXConnector connector;   

    //MBeanServerConnection

    private MBeanServerConnection mbsc;   

    //单一实例

    private static ArcTestJMX_Manage singleton;

   

    public static void main(String[] args) throws Exception {

        //管理初始化和连接远程的JMX代理

        ArcTestJMX_Manage manager = ArcTestJMX_Manage.getDefault();

        //对资源(这里是ArcTest程序)进行管理

        manager.manageArcTest();

    }

   

    public void manageArcTest() throws Exception {

        String domain = mbsc.getDefaultDomain();

        ObjectName stdMBeanName =

                new ObjectName(domain +":type=ArcTestJmx");

        System.out.println("\nCreate ArcTestJmx MBean...");

        //调用MBean方法start,无参数和返回值

        mbsc.invoke(stdMBeanName, "start", null, null);

        //对MBean的属性StartAngle赋值,设为30

        mbsc.setAttribute(stdMBeanName,

                new Attribute("StartAngle", new Integer("30")));

        //调用MBean方法fill,无参数和返回值

        mbsc.invoke(stdMBeanName, "fill", null, null);

    }

       

    /**

     *返回JMX管理应用的单一实例

     */

public synchronized static ArcTestJMX_Manage getDefault() throws

Exception {

        if(singleton == null) {

            singleton = new ArcTestJMX_Manage();

            singleton.connect();

        }

        return singleton;

    }

   

    public void connect() throws Exception {

        //创建JMX Agent的URL

        JMXServiceURL url = new JMXServiceURL(

"service:jmx:rmi:///jndi/rmi://localhost:9999/server");

        //连接JMXConnector

        connector = JMXConnectorFactory.connect(url, null);

        //得到MBeanServerConnection

        mbsc = connector.getMBeanServerConnection();

    }

   

    public void close() throws Exception {

        connector.close();

    }  

}

* 说明:   MBean的命名通常使用关键字type=MBean的类名。比如例子中定义的MBean的ObjectName是type=ArcTestJmx。在后面对AMX的介绍中,可以看到GlassFish对MBean的ObjectName有着更细致的约定。


15.2  JMX的基本概念

15.2.1  JMX的3层架构

JMX技术解决的是如何管理各类资源的问题。完整的JMX应用所关联的对象分为以下两类。

l   可管理资源(Manageable Resources):JMX管理的资源可以是系统、应用、服务、设备或是一个用户,只要这些对象可以通过Java语言描述。当这些资源通过MBean描述时,它们就被封装成为可管理资源。

l   管理应用(Manage Application):管理应用指各类通过JMX管理接口对可管理资源所进行的操作。

JMX要将各种资源封装成可管理资源,同时为各类管理应用访问可管理资源提供支持。三者的关联如图15-2所示。

图15-2  JMX应用所关联的两类对象

JMX应用架构被分成3个层次,分别为:装配层 (Instrumentation Level)、代理层(Agent Level),分布式服务层(Distributed Service Level),如图15-3所示。对照图15-2,中间的代理层提供类似总线的连接和可插拔服务的相关实现,装配层对应着可管理资源的相关实现,分布式服 务层对应着管理应用的相关实现。

图15-3  JMX架构图

(1)   装配层(Instrumentation Level)

装配层的主要任务就是对资源进行封装,使之成为可管理资源。所谓封装,就是通过将资源用类似Java Bean的方式描述出来。当资源以这种方式被封装成为可管理资源后,就被称作MBean(Management Bean)。

(2)   代理层(Agent Level)

代理层位于装配层和分布式服务层之间,包含 MBean服务器、注册的MBean和连接器。代理层的作用体现在内外两方面:对内它通过MBean服务器(Managed Bean Server)维护着MBean的生命周期(包括注册和注销MBean),同时为所注册的MBean提供各类服务;对外通过连接器将已注册的MBean的 管理接口暴露给外面的管理应用使用。

(3)   分布式服务层(Distributed Service Level)

分布式服务层驻留着管理应用。管理应用通过连接器 (Connector)与MBean服务器建立连接,并通过管理接口(Management Interface)去访问各个Mbean所包装的可管理资源。JMX Remote API Specification(JSR-166)对分布式服务层的应用给出了具体的规范。

JMX的3层架构的每一层都分布着不同的JMX组件,下面分别加以介绍。

15.2.2  MBean组件

MBean是Management Bean的缩写,负责将可管理资源和服务封装成类似Java Bean的形式。通过MBean的特性可以访问可管理资源的各类信息。MBean对资源的封装体现在以下几个方面:

l   属性名称及读写类型。

l   对资源的操作。

l   指定类型的通知。

说明:JVM已经默认被封装成可管理对象。可通过它去访问内置的JVM,从而远程监控并管理JVM。

MBean在JMX的3层架构中位于装配层和代理层,这两层中的MBean有着不同的作用:位于装配层的MBean被用来封装可管理资源,而位于代理层的MBean被用来封装MBean服务器提供的代理服务(比如定时器服务和监视器服务)。

从MBean的实现上来看,MBean分为两种类型:标准(Standard)MBean和动态(Dynamic) MBean。其中动态MBean又进一步分为Open MBean和Model MBean,如图15-4所示。

图15-4  MBean的分类

1. 标准(Standard)MBean

标准MBean适用于描述那些数据稳定且可被事先准 确定义的资源。标准MBean就是一个普通Java Bean,MBean服务器通过Java的内省(Introspection)机制来获知标准MBean的属性、事件和方法,只是这里内省所遵循的命名规 定是JMX特有的命名约定。

在各类MBean中,标准MBean的实现最为快捷方便。但在某些情况下,标准MBean并不能满足需要,比如一个资源对于不同用户有着不同的访问接口,或在不同运行状态有着不同的访问接口,这时管理接口将无法预先定义,这时就需通过动态MBean来解决问题。

2. 动态(Dynamic)MBean

动态MBean适用于描述那些要在运行时才可确切知 道的数据结构的资源。与标准 MBean不同的是,动态MBean所暴露的管理接口不必事先确定,而是可根据运行时的情况,判断生成最终的管理接口。比如用以描述配置的MBean,可 能需要通过对配置文件的分析来最终获得属性的名称和类型。

动态MBean的标志是实现了javax.manangement.DynamicBean接口。接口中的方法()所返回的就是要对外发布的管理接口。与标准MBean不一样的是,MBean服务器不是通过内省,而是通过()方法的返回值来获取动态Bean的管理接口。

动态MBean和MBean服务器所支持的接口 非常一致,这是因为MBean服务器要对标准MBean的管理接口进行内省的实现,而这也是动态MBean自身要实现的逻辑。这样,管理应用在通过 MBean服务器访问两类MBean时感觉不到任何差别,因为两者的差别在MBean服务器内部被屏蔽掉了。

Model MBean和Open MBean都是动态MBean的延伸。

(1)   Model MBean预先实现了某些行为,并允许在运行过程中间进一步定制这些行为。Model MBean的标志是实现Model MBean接口,并在ModelBeanInfo对象中提供元数据的资源配置。Model MBean提供了将资源适配到MBean接口的能力。

(2)   Open MBean是一类特殊的动态Mbean,它的特征是只针对特定对象,比如原始的数据类型(如int和float)和复合的数据类型。

3. MBean与Java Bean比较

Java Bean是最早的Java规范,它实际上是一套命名规范和设计模式。MBean沿用了Java Bean的一些命名规范并继承了Java Bean的许多特性。比如,通过内省机制得到MBean的属性和方法;通过辅助类MBeaninfo提供了更精确的关于MBean的信息;为特定需求动态 MBean所提供的对MBeaninfo的实现类似于Java Bean的Customer接口的实现;通用工具如JConsole对访问MBean的支持类似于IDE(集成开发环境)对访问Java Bean的支持。

15.2.3  MBean服务器

MBean服务器位于JMX的3层架构中的代理层, 它是代理层的核心,负责完成代理层的主要功能。MBean服务器管理着MBean的生命周期,即注册和注销,并向MBean提供各类服务,包括动态加载 (Advanced Dynamic Loading)服务、监视(Monitor)服务、定时器(Timer)服务和关联(Relation)服务。

MBean服务器和它所代理的MBean所驻留的 Java虚拟机被称作代理端(Agent Side),而管理应用所驻留的Java虚拟机被称作管理端(Manage Side)。管理端对代理端的访问多为远程访问,而MBean服务器对其代理的MBean的访问都是本地访问。

1. Object Name

Object Name是MBean的唯一标识,它在MBean向MBean服务器中注册时指定。管理应用可以通过这个标识来寻址MBean。Object Name体现了MBean服务器关于MBean的命名机制,这一机制是管理应用和MBean之间实现松耦合的关键。Object Name的语法如下:

[domainName]:property=value[,property=value]*

可以看到,Object Name由两部分组成:域名和一组关键属性,具体说明如下。

(1)   域名(Domain Name)

关于域名的命名和Java包的约定一致,即“反向的DNS名 + 组织自定义的字串”。比如由Sun公司开发的MBean,其DNS名是sun.com,则其域名格式是com.sun.MyDomain。

(2)   关键属性(Key Properties)

关键属性是一些Key-value对,通过它们可以为MBean在指定的域中添加包括名字、类型和说明等属性,但这些属性可以不是MBean的实际属性。

【例15.1】几个Object Name的实例:

MyDomain:description=Printer,type=laser

MyDomain:description=Disk,capacity=2

DefaultDomain:description=Disk,capacity=1

DefaultDomain:description=Printer,type=ink

2. 管理接口

MBean 被MBean服务器注册并启用后,MBean服务器将解析MBean所获得的管理接口并将其暴露给外部的管理应用。管理应用必须通过MBean服务器提供 的管理接口来访问MBean,而不能直接访问MBean。MBean服务器提供的管理接口具体包含以下几部分:

l   管理注册的MBean。包括属性读写和方法调用。

l   接受MBean发出的通知。

l   实例化并注册MBean。这些MBean可以是来自驻留在代理端的类(Class),也可以是从网络或本地装载来的新类。

【例15.2】注册Mbean:

MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

CacheControl MBean = new CacheControl();

//注册时,必须给MBean指定一个唯一的object name

ObjectName name = new ObjectName("com.example:type=CacheControl");

mbs.registerMBean(MBean, name);

// 也可以使用下句:

//mbs.createMBean(CacheControl.class.getName(), name);

3. 描述MBean服务器的Delegate MBean

在JMX规 范中,MBean服务器默认定义了一个叫做JMImplementation的域,并在这个域中默认地注册了一个叫 MBeanServerDelegate的MBean。这个MBean所标识和描述的就是MBean服务器。MBean服务器发出的事件通知就是由这个对 象播发出去的。

MBeanServerDelegate所定义的属性都是只读的。它的对象名是JMImplementation:type= MBeanServerDelegate。用JConsole连接到任一个MBean服务器,都可以看到这个对象,如图15-5所示。

图15-5  描述MBean服务器的Delegate MBean

15.2.4  JMX消息模型

Notification(消息)被用来特指JMX 应用中的事件。JMX消息模型所描述的是MBean之间交换信息的机制。JMX消息模型包括消息播发器、JMX消息、侦听器(Listener)和过滤器 等对象。JMX消息经过过滤器的筛选,由消息播发器发送给消息侦听器。JMX消息模型如图15-6所示。

图15-6  JMX消息模型

消息播发器和侦听器可以是任意对象,只要它们实 现了相应的接口,MBean和MBean服务器都可以充当消息播发器或侦听器的角色。侦听器需支持NotificationListener接口,这个接 口定义了事件被触发时侦听器所要完成的操作。消息播发器则要求维护一个所要通知的消息侦听器的列表,它通常实现了接口 NotificationBroadcaster或NotificationEmitter。过滤器须实现NotificationFilter 接口,并通过实现接口中的方法isNotificationEnabled(Notification notification)来决定过滤哪些消息。

JMX消息是Notification类或其子类的实例,它封装了播发器所要通知侦听器的内容和相关信息,参见表15-1。

表15-1  JMX消息的构成

属  性

说  明

Source

消息播发器的实例引用

message

对Notification的说明

SequenceNumber

Notification实例的唯一标识

                                                                                                                                                                        续表

属  性

说  明

TimeStamp

时间戳。Notification何时生成

Type

用点标注法表示的JMX消息类型。比如JMX.MBean.registered

UserData

具体的要传达的信息

JMX通知机制与Java Bean的事件机制主要的不同在于:JMX通知在播发器和侦听器之间的传递是统一的。这样播发器和侦听器无需预先约定事件类型,而对不同通知的差别可以通过Notification类的Type和通用的UserData来表述。

15.2.5  代理服务(Agent Service)

MBean服务器提供给注册MBean的服务被称作 JMX代理服务,它们本身也被封装成MBean的形式。代理服务位于JMX架构中的代理层。代理服务主要包括四类:动态加载(Advanced Dynamic Loading)服务、监视(Monitor)服务、定时器(Timer)服务和关联(Relation)服务。分别说明如下。

(1)   动态加载服务——通过获取包含MBean相关信息的XML文件MLet(Management Applet),实例化并注册MBean。

(2)   监视服务——监视MBean的属性变化,当属性值的变化超出预定义的范围时,相应地发出通知。根据所监视的属性,JMX定义了三类监视器。

l   计数器监视器(Counter Monitor):监视整型(Integer)类型的属性值,当数值变更幅度超出预设时触发事件。

l   度量监视器(Gauge Monitor):监视整型(Integer)或浮点类型(Floating)的属性值,当数值超出预设的上限或下限时触发事件。

l   字符串监视器(String Monitor):监视字符串(String)类型的属性值,当字符串变更时触发事件。

(3)   定时器服务——在指定时间触发事件或周期性地重复触发事件。

(4)   关联服务——定义MBean之间的关联并且维护关联的一致性。这方面的实现由包javax.management.relation提供。

15.2.6  连接器(Connector)

连接器位于JMX的3层架构中的分布式服务层。连接 器负责建立MBean服务器和管理应用之间的通信。连接器由一个驻留在代理层的连接服务器(Connector Server)和管理应用的连接客户端(Connector Client)构成。连接器屏蔽了协议的差别和协议连接的复杂性,使得管理应用和MBean服务器之间的通信过程以协议无关的方式进行。在Java SE中,RMI连接器被指定为默认的连接器。

分布式服务层中另一个用来帮助建立管理应用和 MBean服务器连接的组件是协议适配器(Protocol Adaptor)。协议适配器支持建立在某个协议之上的对MBean的访问。比如通过HTML适配器可以在Web浏览器中显示一个MBean。Java SE默认并未包含任何适配器。

【例15.3】构建到GlassFish应用服务器的JMX连接:

//构建JMX Agent URL

JMXServiceURL url = new JMXServiceURL(

"service:jmx:rmi:///jndi/rmi://localhost:8686/jmxrmi");

Map env = new Hashtable();

//访问GlassFish应用服务器的用户名和口令

String[] creds = {"admin", "adminadmin"};

env.put(JMXConnector.CREDENTIALS, creds);

//创建JMXConnector

JMXConnector connector = JMXConnectorFactory.connect(url, env);

//得到MBeanServerConnection       

MBeanServerConnection mbsc = connector.getMBeanServerConnection();

例中通过JMXServiceURL来指定建立连接所需的信息,工厂类JMXConnectorFactory通过JMXServiceURL提供的信息创建了连接器connector,通过这个连接其可以进一步访问驻留在MBean服务器中的MBean。

JMXServiceURL提供了关键的连接信息,它的格式如下:

service:jmx:protocol:sap

其中protocol为传输协议,本例中为rmi。sap是查找到连接器服务器的地址位置,本例中为///jndi/rmi://localhost:8686/jmxrmi。

阅读(1699) | 评论(0) | 转发(0) |
0

上一篇:ubuntu 升级

下一篇:java jndi

给主人留下些什么吧!~~