Spring与MX4J集成实现JMX管理 (转载)
MX4J是一个开源JMX管理框架,支持JSR3 (JMX) 和JSR160 (JMX RemoteAPI)。通过Spring将MX4J集成到我们的应用系统中,可以通过HTTP协议适配,能够基于Web的方式来实现对应用系统的监控和管理。这里,使用的版本分别为:Spring 2.5
MX4J 3.0.2
MX4J对应的几个JAR文件,加入到CLASSPATH:
mx4j.jarmx4j-impl.jarmx4j-jmx.jarmx4j-remote.jarmx4j-rimpl.jarmx4j-rjmx.jarmx4j-tools.jar首先,给出Spring的完整配置,如下所示:
view plain- <?xml?version="1.0"?encoding="UTF-8"?>??<beans?xmlns="http://www.springframework.org/schema/beans"??
- ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?xmlns:p="http://www.springframework.org/schema/p"??????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">??
- ??????<bean?id="exporter"?class="org.springframework.jmx.export.MBeanExporter"??
- ????????depends-on="mbeanServer">??????????<property?name="beans">??
- ????????????<map>??????????????????<entry?key="CONFIG.SHIRDRN.ORG:name=config"?value-ref="config"?/>??
- ????????????????<entry?key="MX4J.SOURCEFORGE.COM:name=httpAdaptor"?value-ref="httpAdaptor"?/>??????????????????<!--?
- ????????????????<entry?key="jdmk.sun.com:name=adaptorServer"?value-ref="adaptorServer"?/>?????????????????-->??
- ????????????</map>??????????</property>??
- ????????<property?name="server"?ref="mbeanServer"?/>??????????<property?name="assembler">??
- ????????????<ref?bean="assembler"?/>??????????</property>??
- ????</bean>??????<bean?id="assembler"??
- ????????class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">??????????<property?name="managedInterfaces">??
- ????????????<list>??????????????????<value>org.shirdrn.jmx.mx4j.SelectedMethodsInterface</value>??
- ????????????</list>??????????</property>??
- ????</bean>??????<bean?id="mbeanServer"?class="org.springframework.jmx.support.MBeanServerFactoryBean"?/>??
- ????<bean?id="httpAdaptor"?class="mx4j.tools.adaptor.http.HttpAdaptor">??????????<property?name="processor">??
- ????????????<ref?bean="xsltProcessor"?/>??????????</property>??
- ????????<property?name="host">??????????????<value>172.20.9.23</value>??
- ????????</property>??????????<property?name="port"?value="9988"?/>??
- ????</bean>??????<bean?id="xsltProcessor"?class="mx4j.tools.adaptor.http.XSLTProcessor"?/>??
- ????<bean?id="config"?class="org.shirdrn.jmx.mx4j.MyConfiguration"?/>????????
- ????<!--??????<bean?id="adaptorServer"?class="com.sun.jdmk.comm.HtmlAdaptorServer">??
- ????????<property?name="port">??????????????<value>9999</value>??
- ????????</property>??????</bean>??
- ????-->????
- </beans>???
上面配置中,比较核心的是MX4J的HTTP适配器类:mx4j.tools.adaptor.http.HttpAdaptor,它有一个processor属性,使用MX4J已经实现的mx4j.tools.adaptor.http.XSLTProcessor来对其注入。XSLTProcessor实现了MX4J定义的XML转换成为浏览器可以解析的格式的文档,就Web网页。
通过MX4J的源码可以看到,在mx4j-3.0.2/src/tools/mx4j/tools/adaptor/http/xsl目录下面,可以看到MX4J定义的一些XSLT模板,例如serverbydomain.xsl为Web控制台首页模板:
view plain- <?xml?version="1.0"?>??<!--??
- ?Copyright?(C)?The?MX4J?Contributors.???All?rights?reserved.??
- ???This?software?is?distributed?under?the?terms?of?the?MX4J?License?version?1.0.??
- ?See?the?terms?of?the?MX4J?License?in?the?documentation?provided?with?this?software.????
- ?Author:?Carlos?Quiroz?(tibu@users.sourceforge.net)???Revision:?$Revision:?1.2?$??
- ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????-->??<xsl:stylesheet?xmlns:xsl="http://www.w3.org/1999/XSL/Transform"?version="1.0">??
- ???<xsl:output?method="html"?indent="yes"?encoding="ISO-8859-1"/>?????<xsl:include?href="common.xsl"?mce_href="common.xsl"/>??
- ???<xsl:include?href="xalan-ext.xsl"?mce_href="xalan-ext.xsl"/>????
- ???<xsl:param?name="html.stylesheet">stylesheet.css</xsl:param>?????<xsl:param?name="html.stylesheet.type">text/css</xsl:param>??
- ???<xsl:param?name="head.title">serverbydomain.title</xsl:param>????
- ???<!--?Invoked?when?a?query?error?is?produced?-->?????<xsl:template?match="Domain"?name="error">??
- ??????<xsl:for-each?select="Exception">???????????<tr>??
- ????????????<td?class="serverbydomain_domainline"?colspan="5">?????????????????<xsl:call-template?name="str">??
- ??????????????????<xsl:with-param?name="id">serverbydomain.error.query</xsl:with-param>????????????????????<xsl:with-param?name="p0">??
- ?????????????????????<xsl:value-of?select="@errorMsg"/>????????????????????</xsl:with-param>??
- ???????????????</xsl:call-template>??????????????</td>??
- ?????????</tr>????????</xsl:for-each>??
- ???</xsl:template>????
- ???<!--?Invoked?to?display?each?domain?-->?????<xsl:template?match="Domain"?name="domain">??
- ??????<xsl:for-each?select="Domain">???????????<xsl:sort?data-type="text"?order="ascending"?select="@name"/>??
- ?????????<tr>??????????????<td?class="serverbydomain_domainline"?colspan="5">??
- ???????????????<xsl:call-template?name="str">????????????????????<xsl:with-param?name="id">serverbydomain.domain.label</xsl:with-param>??
- ??????????????????<xsl:with-param?name="p0">???????????????????????<xsl:value-of?select="@name"/>??
- ??????????????????</xsl:with-param>?????????????????</xsl:call-template>??
- ????????????</td>??????????????<xsl:call-template?name="mbean"/>??
- ?????????</tr>????????</xsl:for-each>??
- ???</xsl:template>????
- ???<!--?invoked?for?each?mbean?-->?????<xsl:template?match="MBean"?name="mbean">??
- ??????<xsl:for-each?select="MBean">???????????<xsl:sort?data-type="text"?order="ascending"?select="@objectname"/>??
- ?????????<xsl:variable?name="classtype">??????????????<xsl:if?test="(position()?mod?2)=1">darkline</xsl:if>??
- ????????????<xsl:if?test="(position()?mod?2)=0">clearline</xsl:if>???????????</xsl:variable>??
- ?????????<xsl:variable?name="objectname">??????????????<xsl:call-template?name="uri-encode">??
- ???????????????<xsl:with-param?name="uri"?select="@objectname"/>??????????????</xsl:call-template>??
- ?????????</xsl:variable>???????????<tr?class="{$classtype}"?width="100%">??
- ????????????<td?width="35%"?align="left"?class="serverbydomain_row">?????????????????<a?href="mbean?objectname={$objectname}"?mce_href="mbean?objectname={$objectname}">??
- ??????????????????<xsl:value-of?select="@objectname"/>?????????????????</a>??
- ????????????</td>??????????????<td?width="20%"?align="left"?class="serverbydomain_row">??
- ???????????????<p>????????????????????<xsl:value-of?select="@classname"/>??
- ???????????????</p>??????????????</td>??
- ????????????<td?width="35%"?align="left"?class="serverbydomain_row">?????????????????<p>??
- ??????????????????<xsl:value-of?select="@description"/>?????????????????</p>??
- ????????????</td>??????????????<td?width="10%"?align="right"?class="serverbydomain_row">??
- ???????????????<p>????????????????????<a?href="delete?objectname={$objectname}"?mce_href="delete?objectname={$objectname}">??
- ?????????????????????<xsl:call-template?name="str">??????????????????????????<xsl:with-param?name="id">serverbydomain.mbean.unregister</xsl:with-param>??
- ?????????????????????</xsl:call-template>????????????????????</a>??
- ???????????????</p>??????????????</td>??
- ?????????</tr>????????</xsl:for-each>??
- ???</xsl:template>????
- ???<!--?Main?template?-->?????<xsl:template?match="Server">??
- ??????<html>???????????<xsl:call-template?name="head"/>??
- ?????????<body>??????????????<table?width="100%"?cellpadding="0"?cellspacing="0"?border="0">??
- ???????????????<tr?width="100%">????????????????????<td>??
- ?????????????????????<xsl:call-template?name="toprow"/>???????????????????????<xsl:call-template?name="tabs">??
- ????????????????????????<xsl:with-param?name="selection">server</xsl:with-param>???????????????????????</xsl:call-template>??
- ?????????????????????<xsl:variable?name="query">??????????????????????????<xsl:call-template?name="str">??
- ???????????????????????????<xsl:with-param?name="id">serverbydomain.server.query</xsl:with-param>??????????????????????????</xsl:call-template>??
- ?????????????????????</xsl:variable>???????????????????????<table?width="100%"?cellpadding="0"?cellspacing="0"?border="0">??
- ??????????????????????????<tr>??
- ???????????????????????????<td?class="page_title">????????????????????????????????<xsl:call-template?name="str">??
- ?????????????????????????????????<xsl:with-param?name="id">serverbydomain.server.title</xsl:with-param>????????????????????????????????</xsl:call-template>??
- ???????????????????????????</td>?????????????????????????????<form?action="serverbydomain">??
- ??????????????????????????????<td?align="right"?class="page_title">???????????????????????????????????<xsl:call-template?name="str">??
- ????????????????????????????????????<xsl:with-param?name="id">serverbydomain.server.filter</xsl:with-param>???????????????????????????????????</xsl:call-template>??
- ?????????????????????????????????<input?type="text"?name="querynames"?value="*:*"/>???????????????????????????????????<input?type="submit"?value="{$query}"/>??
- ??????????????????????????????</td>?????????????????????????????</form>??
- ????????????????????????</tr>???????????????????????</table>??
- ?????????????????????<table?width="100%"?cellpadding="0"?cellspacing="0"?border="0">??????????????????????????<xsl:call-template?name="domain"/>??
- ????????????????????????<xsl:call-template?name="error"/>???????????????????????</table>??
- ?????????????????????<xsl:call-template?name="bottom"/>????????????????????</td>??
- ???????????????</tr>??????????????</table>??
- ?????????</body>????????</html>??
- ???</xsl:template>??</xsl:stylesheet>??
Spring配置中通过实例化一个HttpAdaptor,注册到MBeanServer中,实现基于HTTP协议远程访问管理和监控。org.shirdrn.jmx.mx4j.MyConfiguration我们定义的一个MBean,也注册到MBean Server中,实现JMX的管理与监控,代码如下所示:
view plain- package?org.shirdrn.jmx.mx4j;????
- public?class?MyConfiguration?{??????private?long?id?=?System.currentTimeMillis();??
- ????private?String?name;??????public?MyConfiguration()?{??
- ????????super();??????}??
- ????public?MyConfiguration(long?id,?String?name)?{??????????super();??
- ????????this.id?=?id;??????????this.name?=?name;??
- ????}??????public?long?getId()?{??
- ????????return?id;??????}??
- ????public?void?setId(long?id)?{??????????this.id?=?id;??
- ????}??????public?String?getName()?{??
- ????????return?name;??????}??
- ????public?void?setName(String?name)?{??????????//?通过JMX管理调用时,更新id的值??
- ????????this.id?=?System.currentTimeMillis();??????????this.name?=?name;??
- ????}??????public?String?show()?{??
- ????????StringBuffer?sb?=?new?StringBuffer().append("id=").append(id).append(??????????????????",?name=").append(name);??
- ????????System.out.println("show()="?+?sb.toString());??????????return?sb.toString();??
- ????}??}??
但是,Spring配置中的org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler对MBean暴露的操作进行了限制,主要是通过我们定义的接口org.shirdrn.jmx.mx4j.SelectedMethodsInterface来指定需要将MBean的哪些内容暴露给JMX管理,接口如下所示:
view plain- package?org.shirdrn.jmx.mx4j;????
- public?interface?SelectedMethodsInterface?{????????public?long?getId();????
- ????public?void?setName(String?name);??????public?String?getName();??
- ????public?void?show();????}??
最后,我们可以初始化Spring的IOC容器,启动MX4J的HttpAdaptor服务,实现通过Web控制台的JMX管理,代码如下所示:
view plain- package?org.shirdrn.jmx.mx4j;????
- import?java.io.IOException;??import?javax.management.MalformedObjectNameException;??
- import?mx4j.tools.adaptor.http.HttpAdaptor;??import?org.springframework.context.ApplicationContext;??
- import?org.springframework.context.support.ClassPathXmlApplicationContext;????
- public?class?JMXTest?{??????public?static?void?main(String[]?args)?throws?IOException,??
- ????????????MalformedObjectNameException,?Exception?{??????????ApplicationContext?ctx?=?new?ClassPathXmlApplicationContext(??
- ????????????????new?String[]?{?"org/shirdrn/jmx/mx4j/applicationContext.xml"?});??????????HttpAdaptor?httpAdaptor?=?(HttpAdaptor)?ctx.getBean("httpAdaptor");??
- ????????httpAdaptor.start();??????}??
- }??
启动成功后,可以通过浏览http://192.168.1.102:9988,可以看到我们注册的MBean,并对其进行管理和监控。