最近公司用到一些关于 JMX 的使用,在我的 BLOG 之前介绍过 JMX。
一个简单的 JMX 结构由以下几个步骤去完成:
① 需要一个 MBeanServer 作为一个容器,去装载你的 MBean 如下创建:
MBeanServer server = ("Local");
① ObjectName,JDK 文档对它的描述是这样的:表示 MBean 的对象名,或者能
够与多个 MBean 名称相匹配的模式。我们可以从字面上了解到他是干什么的了,
就好比一个 KEY, 当我们的 MBean 注入 MBeanServer 后总要有一个标识它,以
方便我们以后通过这个 KEY 去找过我们的 MBean.如下创建:
ObjectName manager = new ObjectName("NCS:name=scheduler");
① 将我们需要进行管理的 MBean 注册到 MBeanServer 中,具体如下:
(new IScheduler(), manager);
这样就算告一段落了,完成以上步骤后,将实现一个 MBeanServer(一个容器)
中拥有多个 MBean(受管理的类).这就是 JMX 的基本实现。
那么如果要对 MBean 进行管理当然少不了一些管理机制,如 SUN 自己提供的
HtmlAdaptorServer 和 Jconsole。HtmlAdaptorServer 可以通过 WEB 对 MBean 进
行管理,Jconsole 则是 C/S 结构的。下面列举一下 HtmlAdaptorServer 的使用方
法:
HtmlAdaptorServer adapter = new HtmlAdaptorServer();
(adapter, adapterName);
以上代码片段可以看出其实 HtmlAdaptorServer 也就是个 MBean,而这个 MBean
可访问注册在 MBeanServer 的其他 MBean 而已。
最后启动 HtmlAdaptorServer :
();
完整代码片段:
//XXX()自定义方法名吧!
public void XXX(){
try {
// create MBSERVER name is WUBINSERVER
List l = (null);
if (() > 0) {
server = (MBeanServer) (0);
} else {
server = ("Local");
}
// Register HtmlAdaptorserver port is 8082.
ObjectName adapterName = new ObjectName(
"ManagerAgent:name=htmladapter,port=8082");
HtmlAdaptorServer adapter = new HtmlAdaptorServer();
(adapter, adapterName);
// your self objectname register.
ObjectName manager = new ObjectName("NCS:name=scheduler");
(new IScheduler(), manager);
ObjectName manager2 = new ObjectName("NCS:name=scheduler2");
(new IScheduler(), manager2);
// ObjectName manager = new ObjectName("NCS:name=scheduler1");
// (new JobManagerMBeanImpl(), manager);
();
("start.....");
} catch (MalformedObjectNameException e) {
// TODO Auto-generated catch block
();
} catch (InstanceAlreadyExistsException e) {
// TODO Auto-generated catch block
();
} catch (MBeanRegistrationException e) {
// TODO Auto-generated catch block
();
} catch (NotCompliantMBeanException e) {
// TODO Auto-generated catch block
();
} catch (NullPointerException e) {
// TODO Auto-generated catch block
();
}
}
当我们访问本地的 8082 后就可以看到 HtmlAdaptorServer 所提供的管理界面,
但这样的管理界面非常不人性化,(那么丑,怎么见人呢?)那下面我隆重介绍
的就是 WebJMX!!!他能帮我们解决管理界面的问题,让我们可自编写自己
的管理界面。
WebJMX Tag Library Project
首先下载 WEBJMX
(建议下 版本)
那在 DOWNLOADING...的时候我来说一下 WEBJMX 的缺陷。。。(是不是开门一棒,呵呵,
这个我必须先告诉大家一声,不然你发现如果 WEBJMX 并不适合你的工程那下来也没什么意义
了。)
缺陷:
1、WEBJMX 在 2002 年之后就再也没有更新过,最后一个版本是 。很遗憾,有可能以后都不会有新的更新,如果你觉得这
点无法接受,我可以介绍给你其他--------MX4J,不过这个东西很麻烦,如果有兴趣自己去找找资料吧。
2、WEBJMX 是中标签,其他就是利用标签库进行 VIEW。虽说标签已属于过去式,但不代表没有人用它嘛,象我这样的老人家
还在用呢!:)
3、WEBJMX 部署混乱,资料较缺。这点没有什么办法,所以我建议大家下 版本,那个 版本的必须用 ANT 部
署才行,而且里面有很多需要在环境变量里配置的东西,比如 TOMCATHOME 啊 STRUTSHOME 啊等等 HOME。而且我发现
在那 ANT 脚本里本提到有个 包在 TEMP 目录下,结果去寻找也没找到~~~作者的失败之处……
4、WEBJMX 用的 JDK 是 的,但不要紧也支持
好了,废话过后相信你的 WEBJMX 工程也该下好了,把开始我们的 WEBJMX 旅程吧,我希望
它是轻松愉快的。小女子才疏学浅,如果有错误也希望得到批评,但不要象 XX 人在我的留言版
中一样骂我,说偶的 BLOG 是垃圾 BLOG,即便是垃圾 BLOG 也麻烦留点所谓的垃圾评语(为
虾米垃圾)啊,否则就太不知所为了。
我推荐的部署方式并不是用他提供的 ANT 脚本,而是我们自己的部署手段。
我们先用 MYECLIPSE 创建一个 WEB 的 PROJECT。叫 WEBJMX,然后将 WEBJMX 目录下的
org 整个目录拷贝到我们的新建的工程的 src 目录下,然后我们会看到好多红叉叉。不用害怕,
这都算少的了……
然后导入几个包包,这个包包有 MX4J 的、STRUTS 的、QUICK 的还有 JMX 自己的。由于
WEBJMX 是使用 的 JDK。所以当时 SUN 公司还没有将 JMX 放到 JDK 中,. 就没事了。
导完后差不多如下图那么多。
有可能在 org 部署的时候会遇到 enum 这是因为 WEBJMX 使用的 JDK 是 的,
而我们现在基本使用 以上的版本,只要用户自己随便改改变量名就可以了,
别用 enum 这个变量名。
以下展示了两幅图:
这是 HtmlAdaptorServer 的管理界面(①①①① ①①① HTML ①①①①① JMX ①① ①①① ①① HTMLAdaptor
①①① ①①① ①①① )
而这就是 WEBJMX 实例的管理界面,是不是比上面那个人性化的多呢?(①①①①
WbJMX① ①①①① JSP①① ①①① MBeanServer① ①①① ①①① ①① ①①①)
结构(①①①)
WEBJMX 标签包括这些部分(JMX ①①① ①①①① ① ①① ①①①① ①①)
* 一套 JSP 标签和描述标签句法的 TLD 的 Java 类。(①①① ①①①① ① JSP ①①① ①①① TLD ①①① ①① Java
①①①① ①①)
* 由一个 SERVLET 接受页面上表单提交过来的数据。其实在这表单的数据是 WebJMX 标记修
改后生成的。这个表单类似于这样(①①①① SERVLET① ①①① ①①① ①①①①① ①①① ①①①①①. ①①① ① ①① '
①①; s ①①① WebJMX ① ①① ①①①①①①. ① ①①① ①①①① ①①① ①①①① ①①①):
<jmx:formMBean name="changeschedulername" mbean="mbean" invoke="rescheduleJob" label="调
用">于我们常见的 FORM 很不同。
* 通过使用 JSP 标签和 Servlet 调用 AdapterFactory 可以得到 MBeanServers 。(MBeanServers① ①① ①
①① ①①① ①①① ①① Servlet JSP ①① ① ①① AdapterFactory)
结构图:
(①① ①①):
我们可以从上图中看到,WEBJMX 是怎么工作的(虽然不是流程图,但其实一
目了然!)。用户通过 WEB 浏览器通过 HTTP request 触发 ACTION
(JMXACTION SERVLET)然后通过 JMXSerivceAdapter 访问 MBEANSERVER
(能访问 MBEANSERVER 也以为着能管理 SERVER 中的 MBEAN 啦!),那
JMXSerivceAdapter 其实是种适配器,我们之前介绍过的 HTMLAdapter 也是适配
器。
好!下面就开始看看我们的例子来真正认识一下 WEBJMX。
首先作为一个 WEB 程序最重要的当然是 啦,那我们就从它开始……
<?xml version="" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application
"
<web-app>
<!-- register the JMX Action URL as an application parameter-->
<context-param>
<param-name>jmxAction</param-name>
<param-value>jmxAction</param-value>
<description>Default mapping to the JMXAction servlet.</description>
</context-param>
<!-- JMX Action Servlet Configuration -->
<servlet>
<servlet-name>agent</servlet-name>
<servlet-class></servlet-class>
<init-param>
<param-name>locator0</param-name>
<param-value>local</param-value>
</init-param>
<load-on-startup />
</servlet>
<servlet>
<servlet-name>jmxAction</servlet-name>
<servlet-class></servlet-class>
<load-on-startup />
</servlet>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class></servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<!-- JMX Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>jmxAction</servlet-name>
<url-pattern>/jmxAction</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- The Welcome File List -->
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
<!-- JMX Tag Library Descriptor -->
<taglib>
<taglib-uri>/WEB-INF/</taglib-uri>
<taglib-location>/WEB-INF/</taglib-location>
</taglib>
<!-- Struts Tag Library Descriptor -->
<taglib>
<taglib-uri>/WEB-INF/</taglib-uri>
<taglib-location>/WEB-INF/</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/</taglib-uri>
<taglib-location>/WEB-INF/</taglib-location>
</taglib>
</web-app>
非常关键的一个片段:
……
<servlet>
<servlet-name>agent</servlet-name>
<servlet-class></servlet-class>
<init-param>
<param-name>locator0</param-name>
<param-value>local</param-value>
</init-param>
<load-on-startup />
</servlet>
……
我们可以看到有一个叫 agent 的 servlet 被声明了。那在 TOMCAT 启动的时候同
时也被加载了。然后我们来跟踪一下这个 servlet 的内容。
先来看看他的 init()
public void init(ServletConfig config) throws ServletException {
(config);
doInit();
}
很明显,他在初始化的时候调用了 doInit(),然后我们再看看 doInit()
/**
* instanitate some test MBeans.
*/
public void doInit() throws ServletException {
if ((DEBUG_PROP))
log("AgentServlet init()");
List l = (null);
if ((DEBUG_PROP))
log("MBeanServer count:" + ());
if (() > 0)
server = (MBeanServer) (0);
else
server = ("Local");
if ((DEBUG_PROP))
log("initalizing local server instance: " + server);
HtmlAdaptorServer html = new HtmlAdaptorServer(8086);
ObjectName ob_name = null;
try {
ob_name = new ObjectName("Adaptor:name=html,port=8086");
if ((DEBUG_PROP))
log("OBJECT NAME: " + ob_name);
(html, ob_name);
Enumeration e = getServletConfig().getInitParameterNames();
while (()) {
String paramName = (String) ();
if (!("locator"))
continue;
String locator = getServletConfig().getInitParameter(paramName);
l = (locator);
if ((DEBUG_PROP))
log("server list: " + l);
if (() == 0)
return;
if ((DEBUG_PROP))
log("initalizing local server instance: " + server);
server = (MBeanServer) (0);
if ((DEBUG_PROP))
log("server: " + server);
ob_name = new ObjectName("MBeanInfo", "name", "SimpleStandard");
if ((DEBUG_PROP))
log("OBJECT NAME: " + ob_name);
// ("",ob_name);
(new SimpleStandard(), ob_name);
ob_name = new ObjectName("MBeanInfo", "name", "SimpleDynamic");
if ((DEBUG_PROP))
log("OBJECT NAME: " + ob_name);
(new SimpleDynamic(), ob_name);
// ("",
// ob_name);
}
/*
* ObjectName sname = new
* ObjectName("JMImplementation:type=MBeanServerDelegate");
* MBeanInfo minfo = (sname); MBeanAttributeInfo
* attrs[] = (); ("attribute
* count: " +); for(int i = 0; i < ; i++)
* (attrs[i].getName() +" : "
* +(sname, attrs[i].getName()));
*/
} catch (Exception e) {
log("\t!!! Could not create the HTML adaptor !!!");
();
return;
}
();
}
在方法开头就有注释,告诉你这个方法是干什么的了(instanitate some test
MBeans.)初始化一些测试的 MBEN,这个这个还不完全,在方法的内容我们可
以看到,不仅仅是初始化了一些 MBEAN,更重要的是实例了一个
MBEANSERVER 并将适配器和需要管理的 MBEAN 都加载进去了。
创建 MBEANSERVER:
List l = (null);
其实这个方法更适合去查找 MBEANSERVER,但如果没有找到,则会返回一个
默认的 MBEANSERVER,
创建一个 Adaptor:
HtmlAdaptorServer html = new HtmlAdaptorServer(8086);
ob_name = new ObjectName("Adaptor:name=html,port=8086");
注册这个适配器到 MBEANSERVER 中
(html, ob_name);
好,下面是注册我们自己的 MBEAN 到 MBEANSERVER 中去。
ob_name = new ObjectName("MBeanInfo", "name", "SimpleStandard");
其实这个 3 参的构造方法跟 ob_name= new
ObjectName(“MBeanInfo:name=SimpleStandard”);是同理的。
注册:
(new SimpleStandard(), ob_name);
这样,我们的 MBEAN 就被注册到了 MBEANSERVER 中去了。
然后就是启动我们的适配器,让我们的用户可以通过适配器去访问我们的
MBEANSERVER 了。
();
这样,都 和必要的 servlet 都已经写好了。然后就该在我们的页面上
运用我们的标记进行访问我们的 MBEAN 了。
在例子的基本页面
细节我就些了,我们看关键的东西
<a
href="
ekemao1</a>
可以看到这个超连接是跳转到 并带了几个重要的参数。
locator=local,domain=Local 还有 name=Local。哎?!为什么看起来那么想我们
的 ObjectName 的参数?没错!后面两个参数确实是 ObjectName 的参数所用的,
就是 new ObjectName(Local:name=Local)。而 locator=local 这个是 WEBJMX 特定
的,local 是指本地的 MBEANSERVER 访问方式,还有 remote 方式。在这里我
们暂时不说这两种方式,我回在回复栏里细说这两个参数倒底是干什么用的。
然后我们看看 的内容:
头部分:
标记的声明
<%@ page import=".*, .*" %>
<%@ taglib uri="/WEB-INF/" prefix="logic" %>
<%@ taglib uri="/WEB-INF/" prefix="bean" %>
<%@ taglib uri="/WEB-INF/" prefix="jmx" %>
变量的声明,这些变量非常重要,
<bean:parameter id="locator" name="locator"/>
<bean:parameter id="domain" name="domain"/>
<bean:parameter id="serverName" name="name"/>
<jmx:getMBeanServer id="server" attribute="locator"/>
<jmx:getMBeanServer id="server" attribute="locator"/>这个变量也就类似我们获得
了之前在我们的 servlet 中声明好的 MBeanServer,可能你会想,那这个
MBeanServer 是哪来的啊?其实当我们使用<jmx:getMBeanServer>的时候他会根
据后面的 attribute 元素的值去内存中找这个名叫 locator 的 MBeanServer 的实例,
就好比 (“locator")。
体部分:
<jmx:queryNames id="names"
server="server">MBeanInfo:name=SimpleStandard</jmx:queryNames>
以名为 MBeanInfo:name=SimpleStandard 为条件,到 server(之前声明好的
MBEANSERVER 对象)中去找这个 ObjectName 所对应的 MBean,其实
ObjectName 和 MBean 是 1 对 1 的关系,一个 ObjectName 对应一个 MBean,就
好比我们的 Map 类,一个 KEY 对应一个 Value,用 Key 找 Value 一样。
他返回的是一个 List(其实我个人觉得没必要返回 LIST)。
获得单个 MBean:
<logic:iterate id="n" name="names" length="1">
再下去的内容我就不说了,没什么用。接下去我们就自己来做个一 HelloWorld
吧.
新建一个 WEB OBJECT(我这里使用了 MYECLIPSE,东西都是自动就加载的,
如果你用其他的编译器那只好你自己看着大概去做了),然后导入 STRUTS
LIBS(MYECLIPSE 自动生成)。接着在 WEB-INF 目录中放下几个 WEBJMX
重要的文件 ,,,。
这些文件在 WEBJMX 开源项目 中都有。
然后是我们的 ,内容如下:
<?xml version="" encoding="UTF-8"?>
<web-app xmlns="
xmlns:xsi=" version=""
xsi:schemaLocation="
avaee/">
<!-- register the JMX Action URL as an application parameter-->
<context-param>
<param-name>jmxAction</param-name>
<param-value>jmxAction</param-value>
</context-param>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
<!-- JMX Action Servlet Configuration -->
<servlet>
<servlet-name>agent</servlet-name>
<servlet-class>
</servlet-class>
<init-param>
<param-name>locator0</param-name>
<param-value>local</param-value>
</init-param>
<load-on-startup />
</servlet>
<servlet>
<servlet-name>jmxAction</servlet-name>
<servlet-class></servlet-class>
<load-on-startup />
</servlet>
<!-- JMX Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>jmxAction</servlet-name>
<url-pattern>/jmxAction</url-pattern>
</servlet-mapping>
</web-app>
大家看到其实和我先前介绍的例子的 XML 没什么区别,其实这些是必要的。
写好 后,我们来完成 servlet 部分,如上描述的那样,我们有一个
需要去实现:
内容如下:
package ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
public class AgentServlet extends HttpServlet implements JMXTaglibConstants {
/**
*
*/
private static final long serialVersionUID = -5092348467994419208L;
private MBeanServer server = null;
/**
* Initializes the servlet.
*/
public void init(ServletConfig config) throws ServletException {
(config);
try {
doInit();
} catch (MalformedObjectNameException e) {
// TODO Auto-generated catch block
();
} catch (InstanceAlreadyExistsException e) {
// TODO Auto-generated catch block
();
} catch (MBeanRegistrationException e) {
// TODO Auto-generated catch block
();
} catch (NotCompliantMBeanException e) {
// TODO Auto-generated catch block
();
} catch (NullPointerException e) {
// TODO Auto-generated catch block
();
}
}
private void doInit() throws MalformedObjectNameException,
NullPointerException, InstanceAlreadyExistsException,
MBeanRegistrationException, NotCompliantMBeanException {
// TODO Auto-generated method stub
// create MBSERVER name is WUBINSERVER
List l = (null);
if (() > 0) {
server = (MBeanServer) (0);
} else {
server = ("Local");
}
ObjectName adapterName = new ObjectName(
"ManagerAgent:name=htmladapter,port=8083");
HtmlAdaptorServer adapter = new HtmlAdaptorServer();
(adapter, adapterName);
// your self objectname register.
ObjectName manager = new ObjectName("KEKEMAO:name=miaomiao");
(new Kekemao(), manager);
();
}
/**
* Destroys the servlet.
*/
public void destroy() {
if (server != null)
(server);
}
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* @param request
* servlet request
* @param response
* servlet response
*/
protected void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
{
("text/html");
out = ();
// output your page here
("<html>");
("<head>");
("<title>Servlet</title>");
("</head>");
("<body>");
List l = (null);
for (int i = 0; i < (); i++) {
MBeanServer s = (MBeanServer) (i);
("Server: " + s + "<br>");
Iterator it = ((Set) (null, null)).iterator();
while (())
("<li>MBean: " + () + "<br>");
("<hr>");
}
("</body>");
("</html>");
();
}
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request
* servlet request
* @param response
* servlet response
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
{
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request
* servlet request
* @param response
* servlet response
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
{
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*/
public String getServletInfo() {
return "Short description";
}
}
这也跟上面的例子没什么不同,声明一个叫 KEKEMAO:name=miaomiao 的
OBJECTNAME 并对应 Kekemao 的对象,然后注册到 MBEANSERVER 中去。
就这么简单,同时启动了代理。
注意:在上面的 HtmlAdaptorServer 的端口不要重用了。
接下来就是我们的 MBEAN 了
我简单的写了个 MBEAN,基本的 MBEAN 有 2 个类组成的,一个是接口,一个
是它的实现类。WEBJMX 加载 MBEAN 的方式是动态 MBEAN。所以必须有个
接口,而且这个 MBEAN 是有规范的。
MBean 的接口必须以 MBean 为最后几个字。而实现类就拿前几个字母。比如
XXXMBean,然后实现类就叫 XXX。这个还希望大家认真遵循。
接口 KekemaoMBean :
package ;
public interface KekemaoMBean {
/**
* 返回属性用的 BEAN 方法
*
*/
public String getName();
/**
* 没有参数的方法
*
*/
public void sayMiao();
/**
* 带一个参数的方法
* @param miao
*/
public void sayMiaoMiao(String miao);
/**
* Bean 的 Set 方法
*
*/
public void setName(String name);
}
类 Kekemao:
package ;
public class Kekemao implements KekemaoMBean {
private String name = "miaomiao";
public String getName() {
// TODO Auto-generated method stub
return ;
}
public void sayMiao() {
// TODO Auto-generated method stub
("简单方法被调用");
}
public void sayMiaoMiao(String miao) {
// TODO Auto-generated method stub
("带参数的方法被调用,参数的值是" + miao);
}
public void setName(String name) {
// TODO Auto-generated method stub
("MBEAN 中的 Name 被 SET!");
= name;
}
}
可以从上面的接口 KekemaoMBean 和他的实现类 Kekemao 中看到,MBean 不仅
仅是普通的 JAVABEAN,而且他其中还夹杂这一些方法,只要是 MBean 中的方
法都可以被调用被管理。非常爽吧!!
下面我们最后一步,也是最重要的一步了 VIEW 层:
首先是欢迎页面,里头仅仅有个超连接,该超连接跳转到我们的 MBEAN 管理
页面,在跳转的过程做夹带了几个参数,locator=local,domain=KEKEMAO,
name=KEKEMAO。
<%@ page language="java" import=".*" pageEncoding="ISO-8859-1"%>
<%
String path = ();
String basePath = () + "://"
+ () + ":" + ()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP '' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="">
-->
</head>
<body>
<table bgcolor="#000000" width="100%" cellspacing="5" cellpadding="10">
<tr>
<td background="images/">
<table>
<tr>
<td valign="middle" width="0">
<img src="images/" alt="Logo Image" align="top">
</td>
<td valign="middle">
<big align="center"
style="color:#ffffff;font-weight:bold;font-size:16pt">
NCS Remote Management Console</big>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td bgcolor="#ffffff">
<h3>
Production Servers
</h3>
<li>
<a
href="
Server [Web Interface 1]</a>
</li>
</td>
</tr>
</table>
</body>
</html>
<%@ page language="java" import=".*" pageEncoding="GB2312"%>
<%@ page import=".*,.*"%>
<%@ taglib uri="/WEB-INF/" prefix="logic"%>
<%@ taglib uri="/WEB-INF/" prefix="bean"%>
<%@ taglib uri="/WEB-INF/" prefix="jmx"%>
<bean:parameter id="locator" name="locator" />
<bean:parameter id="domain" name="domain" />
<bean:parameter id="serverName" name="name" />
<jmx:getMBeanServer id="server" attribute="locator" />
<%
String path = ();
String basePath = () + "://"
+ () + ":" + ()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP '' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="">
-->
</head>
<body>
<table bgcolor="#000000" width="100%" cellspacing="5" cellpadding="10">
<tr>
<td background="images/">
<table>
<tr>
<td valign="middle" width="0">
<img src="images/" alt="Logo Image" align="top">
</td>
<td valign="middle">
<big align="center"
style="color:#ffffff;font-weight:bold;font-size:16pt">
服务器: <bean:write name="serverName" /> </big>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td bgcolor="#ffffff">
<h3>
"
<bean:write name="domain" />
"中的 MBeans
</h3>
<table cellpadding="6" cellspacing="6" width="100%">
<tr>
<th valign="Top">
objectname
</th>
<th valign="Top">
描述
</th>
<th valign="Top">
MBean 中 name 属性的值
</th>
<th>
无参的方法调用
</th>
<th>
用参数的方法调用
</th>
<th>
属性设置
</th>
<th>
当前 MBean 中 Name 属性的值
</th>
</tr>
<jmx:queryNames id="mbeans"
server="server">KEKEMAO:*</jmx:queryNames>
<logic:iterate id="mbean" name="mbeans">
<tr>
<td valign="Top">
<jsp:getProperty name="mbean" property="canonicalName" />
</td>
<td valign="Top">
<jmx:getMBeanInfo id="mbi" server="server" name="mbean" />
<jsp:getProperty name="mbi" property="description" />
</td>
<td valign="Top">
<jmx:getAttribute name="mbean" server="server" attribute="Name"/>
</td>
<td valign="Top">
<jmx:formMBean name="changeschedulername" mbean="mbean"
invoke="sayMiao" label="简单方法调用">
<jmx:mbean><jsp:getProperty name="mbean"
property="canonicalName" /></jmx:mbean>
</jmx:formMBean>
</td>
<td valign="Top">
<jmx:formMBean name="changeschedulername" mbean="mbean"
invoke="sayMiaoMiao" label="复杂方法调用">
<jmx:mbean><jsp:getProperty name="mbean"
property="canonicalName" /></jmx:mbean>
<jmx:formParameter name="param0" type=""
value="kekemao say miao miao!!" />
</jmx:formMBean>
</td>
<td valign="Top">
<jmx:formMBean name="changeschedulername" mbean="mbean" label="
改变属性值">
<jmx:mbean><jsp:getProperty name="mbean"
property="canonicalName" /></jmx:mbean>
<jmx:formAttribute attribute="Name" type="" />
</jmx:formMBean>
</td>
<td valign="Top">
<jmx:getAttribute name="mbean" server="server" attribute="Name"/>
</td>
</tr>
</logic:iterate>
</table>
</td>
</tr>
</table>
</body>
</html>
哇……终于见到我们的 JMX 标签了,标签的详介看我的回复,在下头 ↓
OK!累死偶了。那总结一下吧:
JMX 是非常有用的一个东西,他针对动态的改变配置信息特别有用,JBOSS 整
个都是 JMX 做出来的呢,在 JBOSS 的管理页面上可以手动的对正在运行中的
JBOSS 进行设置,比如……连接池的连接数设置啊,权限设置啊,Web 程序管
理啊什么什么的。可以看到他多么强大!
那 WEBJMX 是针对 JMX 在 WEB 上管理提出的解决方法,但其实 SUN 自己也
有自己的 WEB 管理适配器,但正如我们知道的,页面不美观,不人性化!!说
白了就是不漂亮,现在我们有了 WEBJMX 就可以自定义管理页面啦。想做成什
么样就什么样!!
WEBJMX 的优点非常大的就是 MBEAN 的管理,我们只要为其提供需要管理的
API 就可以了,非常灵活,这也是归功于 JAVA 本身的机制。在上面的程序中,
可能大家还感觉不出 JMX 的威力,但我们设想,如果上面的 KEKEMAO 这个类
的内容是不仅仅是 SayHello 而是对 JDBC 数据源对象的管理呢?
在 Kekemao 这个类中,把 name 属性变成 host,port,odbc,而方法变成
connoction,stop,isOpen,recon 等等会怎么样?这样大家明白我的意思了吧。这就
是 JMX 所做的!!WEBJMX 不仅仅能做这些,而且还能动态的创建 MBean,
至于具体怎么创建大家参考 WEBJMX 的实例。
当然 WEBJMX 还是有缺陷的:
比如那个<jmx:formMBean>我在页面上展示不想要那个按扭而想要个图片替代
那怎么办??没办法,自己针对他的源代码进行扩展。(可惜的是 WEBJMX 不
在有后续版本,这也许是标记库的时代已经过去的写照吧)。
本实例下载
提取码是:2429727560837814
(大家想看更多关于这篇文章的信息,请到师姐的博客去看
~~