- 浏览: 412074 次
- 性别:
- 来自: 北京
最新评论
-
MCLoginandPwd:
分享一个代码生成器,http://blog.csdn.net/ ...
利用MyBatis Generator自动创建代码 -
astarring:
本人写了一个带界面版的mybatis geneator,htt ...
利用MyBatis Generator自动创建代码 -
spp_1987:
楼主, 有 操作 xsd 字符串 跟 xml 字符串 的吗? ...
JAXB安装与编译器使用 -
maimode:
814687491 写道List<ResolveInfo ...
Android 语音识别示例 -
maimode:
ydpiaoyun 写道你好,好像没看到数据库驱动配置的地方如 ...
利用MyBatis Generator自动创建代码
以下转自:http://www.ibm.com/developerworks/cn/java/l-jmx2/index.html
Web 应用系统总算开发了,接下来该如何让客户(Web 应用系统的管理员)轻松管理我的一堆配置文件,或者如何实现动态修改系统运行属性,同时又让客户不需要过多的了解配置文件的内容就能够实现这些管理呢?这是许多刚刚结束 Web 应用系统前期开发的系统分析人员需要面临的问题。又或者说我想对早已完成 Web 应用系统进行有效的资源管理,希望再添加管理功能的同时,对原有的代码不需要做过多的修改,换句话说就是管理系统与被管理的应用系统做到很好的隔离。JMX 的管理框架(图 1)为你很好的解决了这些问题。
JMX(Java Management Extensions) 是来管理网络,设备,应用程序等资源,它描述了一个可扩展的管理体系结构,并且提供了 JMX API 和一些预定义的 java 管理服务。在撰写本文时,JMX 规范最新版本为 v1.2(http://jcp.org/aboutJava/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 应用构建一个基于 JMX 的管理系统,我们需要做的事情有哪些呢?
1. 针对每一个需要管理的资源创建一个 MBean 的实例,这是 JMX 框架所要求的 , 有两种类型的实例可供选择,一种是直接管理资源的 MBean,一种通过调用资源实例进行管理的 MBean。
2. 编写一个 MBean 描述文件,并描述每一个 MBean,选择基于 XML 的 MBean 描述文件是一个不错的决定。
3. 通过读 MBean 描述文件,生成 MBeanInfo,从而生成一个个 MBean。
4. 将需要进行管理的 MBean 注册到 MBean Server 当中。
5. 编写客户端代码,选择 Web 的方式进行客户端的编码比较 Web 应用的风格,也比较容易实现。
那么一个基于 JMX 的 Web 应用的管理框架已经成形,图 3 是它的基本结构图,虚线部分为基于 JMX 的管理系统。接下来我们按照步骤实现整个管理系统。
有两种方案获得 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 并不十分重要,可以考虑实现的方便进行选择。
为了能够管理 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 应用的情况下,改变数据库连接。
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!"; } } } |
上面的例子是对静态资源的修改,如果需要对正在运行的类实例进行动态修改,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 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 ( " http://jakarta.apache.org/tomcat/tomcat-4.1-doc/mbeans-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 的描述信息,并且保存在 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 的管理框架绝对是一个非常明智的选择。
在下才疏学浅,难免错漏之处,还望有识之士,不吝赐教在下,在下感激于心。
盛戈歆,广州拓微科技有限公司上海分公司高级程序员,对Java的各种技术非常痴迷,参与多个大型的Java项目,并设计实现其的管理系统。Email: shenggexin@topwaver.com。联系电话:021-64366810-170
发表评论
-
HA及集群
2012-01-30 15:27 1566摘自:http://blog.ixpub. ... -
正则表达式中不包含连续字符
2012-02-02 15:15 5246参考资料: http://www.cnblogs.com/d ... -
java反射方式调用私有方法
2011-12-09 17:17 9706以下内容转自:http://blog.csdn.net/sun ... -
java中异常处理机制
2011-10-31 16:41 980本文转载自:http://blog.csdn.net/ilib ... -
JDBC和JTA事务
2011-10-31 16:35 1743JTA和JDBC事务 一般情况下,J2EE应 ... -
重新认识正则表达式group
2011-10-13 17:52 1743转自:http://java.chinaitlab.com/b ... -
转:java中集合框架 ArrayList 和Vector
2011-09-25 21:19 1043ArrayList 和Vector是采用数组方式存储数据,此数 ... -
转:java中堆和栈的区别
2011-09-25 21:01 939堆和栈的区别 栈与堆 ... -
转载:Java正则表达式应用总结
2011-08-10 13:50 1017转载至:http://lavasoft.blog.51cto. ... -
转载:JAVA字符串转日期或日期转字符串
2011-05-09 11:34 1155文章中,用的API是SimpleDateFormat,它是属于 ... -
转载:MyEclipse不编译问题
2011-05-03 17:03 1058本文转载自:http://develo ... -
转载:解决MyEclipse吃内存,让MyEclipse飞起来,MyEclipse速度
2011-04-22 13:55 1191解决MyEclipse吃内存,让MyEclipse飞起来,My ...
相关推荐
简单介绍了JMX规范,在此基础上,讨论了使用JMX体系结构建立网络管理程序的一般方法,最后结合JMX规范和实现方法,分析基于JMX网络管理系统的优势。
基于JMX的IT系统管理关键技术研究与实现,详细介绍了使用jmx的方法
网络游戏-基于JMX的网络业务管理方法及其应用系统.zip
基于JMX技术对分布式应用系统进行监控的设计.docx
基于JMX的Java虚拟机监视系统.pdf
JMX实战 书中不仅有对于基础知识的介绍,还有对于JMX开发中重大的体系架构问题的深入探讨,总结了大量JMX开发中的设计模式,并讨论了框架、安全性与性能...本书内容广泛且深入,同时适用于各个层次的Web应用开发人员。
创建 JMX 检查后,您还可以配置警报以接收警报通知。有关详细信息,请参阅“相关信息”部分。...此外,您可以使用控制台客户端或检查 API 为 Java 应用程序配置 JMX 检查。请参阅“相关信息”部分。
基于Spring+JMX+Tomcat实现资源动态管理
#资源达人分享计划#
JMX(Java Management Extensions)是SUN创建的一套规范。BEA WebLogic Server实现了...OPEN SOURCE的应用服务器JBoss也是基于JMX来实现。并且对之评价很高,认为是目前为止最好的软件集成工具。JBoss的成功依靠于JMX。
基于JMX的JBoss体系结构研究
JMX应用实例与实现,通过一个简单的JavaWeb应用来验证JMX在应用中的植入管理和应用
Java分布式应用学习笔记08JMX规范与各种监控场景
jmx和jmx在glassfish中的应用
JMX一步一步来,从最基本的应用开始入手,快速应用开发。
该方案可把各个应用RFID技术的功能抽象成服务,应用基于J2EE构建方法,综合应用JMX、JMS、Struts等技术。企业应用系统通过请求服务的方式来获取RFID中间件提供的服务。用XML进行数据传输,并提供Web Service接口。
网络的迅速发展对现有网络管理系统的优化提出了迫切的...因此提出了一种利用JMX技术来改进网络管理系统中实时监控管理的一个实现模型。此模型有效地解决了实时监控中的网络拥塞、指标管理混乱、客户端负载过重等问题。
NULL 博文链接:https://jonerxq.iteye.com/blog/1990872
JBoss是纯Java的Web应用服务器,为了保证JBoss服务器的正常运行,在安装JBoss之前首先要确保系统 已经安装了JDK。可以从http://labs.jboss.com/jbossas/downloads/ 下载最新JBoss应用服务器,本章选用JBoss 4.2.2.GA...