16.2 自管理应用开发实例
自管理应用开发包括如何创建并部署Event MBean和Action MBean,以及如何创建并触发相应的管理规则。本实例将用来说明自管理的开发过程。此例程对应光盘中的chapter16\ex1所涉及的项目。此例将关联两个管理规则、两个MBean和一个客户端应用,如图16-2所示。

图16-2 开发实例中的对象
在本例中,所创建的两个管理规则都是监控器类型,所监控的是EventSource的两个属性Number和Str。通过JConsole来修改EventSource的属性Number或Str值,管理规则将触发JMX监控事件。EventAction被来完成事件处理。它将所接受到JMX事件保存到其类型为ArrayList的属性Notifications中。同时,与之关联的客户端应用JmxApp将远程反复地读取EventAction的属性Notifications,并在命令行将其打印出来。
在NetBeans IDE中打开chapter16\ex1涉及的项目。项目的子目录dist下包含一个selfmanagement_monitor.jar文件,该jar文件包含两个MBean:EventAction和EventSource。EventSource是管理规则中的Event MBean,EventAction是管理规则中的Action MBean。它们的代码列举如下。
(1) EventAction.java:
public class EventAction implements NotificationListener,EventActionMBean{
private ArrayList notifications =null;
public EventAction() {
notifications = new ArrayList();
}
/**
* 接受JMX notification并将它们加到自己的属性notifications的列表中
*/
public synchronized void handleNotification(Notification
notification,Object handback) {
notifications.add(notification);
}
public ArrayList getNotifications() {
return notifications;
}
}
(2) EventSource.java:
/**
* 含有两个属性的标准MBean
*/
public class EventSource implements EventSourceMBean{
private String str = "";
private int number = 0;
public void setStr(String s) {
str = s;
}
public String getStr(){
return str;
}
public void setNumber(int i){
number =i;
}
public int getNumber(){
return number;
}
}
16.2.1 创建自管理应用
自管理应用创建的步骤如下。
(1) 部署MBean“EventAction”。
(2) 部署MBean“EventSource”。
(3) 创建字符串型监控器的管理规则。当所监控的Event MBean的属性Str不是预设的值时,此规则将触发JMX消息。
(4) 创建尺度型监控器的管理规则。当所监控的Event MBean的属性Number超出预设的上下限时,此规则将触发JMX消息。
下面将具体说明分别基于管理控制台和命令行asadmin来完成自管理应用的构建的步骤。
1. 基于管理控制台完成
基于管理控制台的完成步骤说明如下。
(1) 部署MBean“EventAction”。
① 启动GlassFish默认域domain1。打开浏览器,访问GlassFish的管理控制台:http://localhost:4848。并输入用户名“admin”和口令“adminadmin”登录。
② 单击左边树形菜单中的Custom MBeans,右边主面板将显示所有的MBean,单击 Deploy按钮。
③ 在Deploy Custom MBean (Step 1 of 2)界面中,选择Jar file to be uploaded to the Application Server单选按钮,再单击Browse,选择光盘中位于chapter16\ex1\selfmanagement_ monitor\dist下的jar文件selfmanagement_monitor.jar。输入MBean实现的类名“jmx_advance. EventAction”,单击Next按钮,如图16-3所示。
④ 在Create Custom MBean (Step 2 of 2)界面中,修改MBean的名称为“EventAction”(也可以选用其他名称,但注意要和后文提到的JmxApp中所引用的MBean名称匹配),最后单击Finish按钮,如图16-4所示。

图16-3 部署自定义的MBean EventAction的步骤1

图16-4 部署自定义的MBean EventAction的步骤2
(2) 部署MBean“EventSource”。
① 单击左边树形菜单中的Custom MBeans,然后单击Deploy按钮。
② 在Deploy Custom MBean (Step 1 of 2)界面中,在Location选项中选择Skip. MBean class has been uploaded。注意:因为MBean class文件已经在部署EventAction MBean时由同一个jar文件上载到服务器端,这里选择不再上载。接着输入MBean实现的类名“jmx_advance.EventSource”,单击Next按钮。
③ 在Create Custom MBean (Step 2 of 2)界面中,修改MBean的名称为“EventSource”(也可以选用其他名称,但需要和后文提到的JmxApp中所引用的MBean名称匹配),最后单击Finish按钮。
(3) 创建字符串型监控器的管理规则。
① 在管理控制台中,依次单击左边树形菜单中的Configuration | Management Rules。
② 在右边的主面板中,单击New按钮来创建新的管理规则。
③ 在New Management Rule (Step 1 of 2)界面中,输入规则名称“strrule”, 选择Event type为“Monitor”, 单击Next按钮,如图16-5所示。

图16-5 创建字符串型监控器的管理规则的步骤1
④ 在New Management Rule (Step 2 of 2)界面中,参照表16-3填入字段的值。
表16-3 创建字符串型监控器的管理规则strrule
|
字 段 |
值 |
说 明 |
|
Observed MBean |
user:impl-class-name=jmx_advance.EventSource, name=EventSource, server=server |
可从所部署的MBean EventSource的Object Name字段里获取信息,并在末尾添加“server=server” |
|
Observed Attribute |
Str |
监控EventSource的“Str”属性 |
|
Granularity Period |
1000 |
每隔1000毫秒读取一次所监控的MBean属性 |
|
Monitor Type |
String |
监控器类型 |
|
Trigger |
从下拉菜单中选择“Equals” |
何时触发 |
|
Value |
javaone |
所比较的字串 |
|
Action |
从下拉菜单中选择“EventAction” |
设定管理规则中的Action MBean |
单击Finish按钮后,管理规则“stringrule”创建完成。当它所监控的EventSource属性Str的值是所指定的字符串“javaone”时,将触发JMX消息,如图16-6所示。

图16-6 创建字符串型监控器的管理规则的步骤2
(4) 创建尺度型监控器的管理规则。
① 在管理控制台,依次单击左边树形菜单中的Configuration | Management Rules。
② 在右边的主面板中,单击New来创建新的管理规则。
③ 在New Management Rule (Step 1 of 2)界面中,输入规则名称“gaugerule”,选择Event Type为“Monitor”,单击Next按钮,如图16-7所示。

图16-7 创建尺度型监控器的管理规则的步骤1
④ 在New Management Rule (Step 2 of 2)界面中,参照表16-4填入字段的值。
表16-4 创建尺度型监控器的管理规则gaugerule
|
字 段 |
值 |
说 明 |
|
Observed Mbean |
user:impl-class-name=jmx_advance.Event-Source, name=EventSource, server=server |
可从所部署的MBean EventSource的Object Name字段中获取信息,并在末尾添加“server=server” |
|
Observed Attribute |
Number |
监控EventSource的Number属性 |
|
Granularity Period |
1000 |
每隔1000毫秒读取一次所监控的MBean属性 |
|
Monitor Type |
Gauge |
监控器类型 |
|
Number Type |
int |
属性类型 |
|
Threshhold |
Low: 5, High:10 |
预设的上下限 |
|
Action |
从下拉菜单中选择“EventAction” |
设定管理规则中的Action MBean |
单击Finish按钮后,管理规则gaugerule创建完成。当它所监控的EventSource属性Number的值超出所指定的范围(5~10)时,将触发JMX消息,如图16-8所示。

图16-8 创建尺度型监控器的管理规则的步骤2
完成上述步骤后,在管理控制台单击左边树形菜单中的Custom MBeans,可以看到两个新部署的MBean:“EventSource”和“EventAction”。依次单击左边树形菜单中的Configuration | Management Rules,可以看到两个新创建的管理规则:“strrule”和“gaugerule”。单击管理规则名的链接,可以进一步看到它们的具体信息。至此,通过管理控制台完成了自管理应用的构建。
2. 基于命令行asadmin完成
基于命令行asadmin的完成步骤说明如下。
(1) 准备工作
先进入目录例程所在的目录,并执行asadmin login(这里假定命令行工具asadmin已经设置在环境变量路径上):
cd <sample>\chapter16\ex1
asadmin login
Please enter the admin user name>admin
Please enter the admin password>
Trying to authenticate for administration of server at host [localhost] and port [4848] ...
An entry for login exists for host [localhost] and port [4848], probably from an earlier login operation.
Do you want to overwrite this entry (y/n)?
Login information is not saved for host name [localhost] and port [4848]
接下来部署MBean。部署之前须事先将包含MBean类的jar文件上载到服务器,这是命令行部署MBean的额外要求。此例需要拷贝selfmanagement_monitor.jar到目录<glassfish-install>\ domains\domain1\applications\mbeans下。
(2) 部署MBean“EventAction”
使用的命令如下:
asadmin> create-mbean --name EventAction jmx_advance.EventAction
Command create-mbean executed successfully.
(3) 部署MBean“EventSource”
使用的命令如下:
asadmin> create-mbean --name EventSource jmx_advance.EventSource
Command create-mbean executed successfully.
(4) 创建字符串型监控器的管理规则
使用的命令如下:
asadmin> create-management-rule --action EventAction --eventtype monitor --eventloglevel WARNING --eventproperties monitortype=stringmonitor:observedobject="user\:impl\-class\-name\=EventSource,name\=EventSource,server\=server ":granularityperiod=1000:observedattribute=Str:stringtocompare=javaone
:stringnotify=notifyequals strrule
Command create-management-rule executed successfully.
(5) 创建尺度型监控器的管理规则
使用的命令如下:
asadmin> create-management-rule --action EventAction --eventtype monitor --eventloglevel WARNING --eventproperties monitortype=gaugemonitor:observedobject="user\:impl\-class\-name\=
EventSource,name\=EventSource,server\=server ":
lowthreshold=5:highthreshold=10:granularityperiod=1000:numbertype=int:
observedattribute=Number gaugerule
Command create-management-rule executed successfully.
至此,通过命令行的方法完成了自管理应用的构建。
16.2.2 运行所创建的自管理应用
自管理应用构建好之后,接下来可以对其运行情况进行检验:首先应启动客户端监控程序JmxApp,接着通过JConsole修改Event Source的属性值来触发管理规则,具体说明如下。
1. 运行客户端监控程序
在NetBeans IDE中运行项目selfmanagement_monitor,将执行jmx_advance.JmxApp类。此类将持续地查看EventAction的属性notificaitons,并在其值发生变化时,将最新的3个JMX消息打印出来。
下面给出JmxApp.java文件的详细代码:
package jmx_advance;
import java.util.*;
import javax.management.*;
import javax.management.remote.*;
/**
* JMX的一个管理应用。持续地查看mbean EventAction的属性Notifications
* 如果收到新的notification ,则将最新3个notification的信息打印出来
*/
public class JmxApp extends Thread{
private JMXConnector connector;
private MBeanServerConnection mbsc;
private String hostname = "localhost";
private int oldsize= 0;
public static void main(String[] args) throws Exception {
JmxApp app= new JmxApp(args);
app.start();
}
public JmxApp(String[] args ) {
if (0 < args.length)
this.hostname = args[0];
System.out.println(
"Start to receive JMX notificaiton from "+ hostname+" ...");
}
/**
* 每隔3秒,远程查看JMX notificaiton
*/
public void run() {
boolean flag = true;
while (flag) {
try {
connect(hostname);
ArrayList notifications = getNotifications();
int newsize = notifications.size();
// Only refresh the output when new notificaiton come in
if (newsize != oldsize) {
oldsize = newsize;
showLatestNotifications(notifications);
}
close();
sleep(3000);
} catch (Exception e) {
e.printStackTrace();
flag = false;
}
}
}
/**
* 如果有新的notification到来,显示最新3个notification的详细信息
*/
public String showLatestNotifications(ArrayList notifications) {
String str = "";
int beginindex= 0;
if (notifications.size()> 3)
beginindex = notifications.size()-3;
System.out.println("-----------------------------------");
System.out.println("Total count for received event is "
+ notifications.size()
+ ". The latest ones are listed as below:\n");
for (int i = beginindex; i<notifications.size(); i++) {
Notification event = (Notification)notifications.get(i);
str += "index:" + (i+1) + ":\n"
+ "type: "+event.getType() + "\n"
+ "Source: "+event.getSource() + "\n"
+ "msg: "+event.getMessage() + "\n"
//+ "seq: "+n.getSequenceNumber() + "\n")
+ "userdata: "+event.getUserData() + "\n\n";
}
System.out.println(str);
return str;
}
/**
* 获取EventAction mbean的属性Notifications
*/
public ArrayList getNotifications() throws Exception {
ObjectName stdMBeanName = new ObjectName(
"user:impl-class-name=jmx_advance.EventAction,
name=EventAction,server=server");
return (ArrayList)mbsc.getAttribute(stdMBeanName, "Notifications");
}
/**
* 建立到JMX的连接
*/
public void connect(String hostname) throws Exception {
JMXServiceURL url = new JMXServiceURL(
"service:jmx:rmi:///jndi/rmi://" + hostname + ":8686/jmxrmi");
Map env = new Hashtable();
String[] creds = {"admin", "adminadmin"};
env.put(JMXConnector.CREDENTIALS, creds);
connector = JMXConnectorFactory.connect(url,env);
mbsc = connector.getMBeanServerConnection();
}
public void close() throws Exception {
connector.close();
}
}
2. 通过JConsole触发管理规则
下面将通过JConsole,来修改EventSource的属性值从而触发管理规则,并由监控程序打印出来由 EventAction所接受到的JMX消息。
(1) 启动JConsole。
(2) 在JConsole的登录面板单击Remote选项卡,输入如表16-5所示的信息。
表16-5 JConsole登录GlassFish所需的信息
|
字 段 |
值 |
|
Host and Id |
localhost |
|
Port |
8686 |
|
User Name |
admin |
|
Password |
adminadmin |
(3) 单击MBean选项卡,再依次单击Tree | User | jmx_advance.EventSource | EventSource | server展开JConsole的树形菜单。可以看到EventSoruce的两个属性“Str”和“Number”,见图16-9。

图16-9 JConsole中所见到的User MBean“EventSource”
(4) 修改Str属性值,先后输入“aaa”和“javaone”。注意JmxApp的输出,可以看到当属性值从“aaa”变为“javaone”时,将触发JMX消息“jmx.monitor.string.matches”:
index:3
type: jmx.monitor.string.matches
Source: com.sun.appserver.selfmanagement:stringtocompare=javaone,version=4,
stringnotify=notifymatch,monitortype=stringmonitor,
granularityperiod=1000,observedattribute=Str
msg:
user data: null
(5) 修改Number属性值,先后输入8、1、7和15。同时切换到运行JmxApp的输出窗口,可以看到当属性值从8变为1时,将触发JMX消息“jmx.monitor.gauge.low”;当属性值从7变为15时,将触发JMX消息“jmx.monitor.gauge.high”:
Start to receive JMX notification...
-----------------------------------
Total count for received event is 2. The latest ones are listed as below:
index:1
type: jmx.monitor.gauge.low
Source: com.sun.appserver.selfmanagement:version=1,differencemode=false,
monitortype=gaugemonitor,highthreshold=10,observedattribute=Number,
numbertype=int,lowthreshold=5
msg:
user data: null
index:2
type: jmx.monitor.gauge.high
Source: com.sun.appserver.selfmanagement:version=2,monitortype=gaugemonitor,
granularityperiod=1000,highthreshold=10,observedattribute=Number,
numbertype=int,lowthreshold=5
msg:
user data: null
若所设的“granularity”是1000毫秒,即每隔1秒钟会发生一次对MBean属性的监控,则输出并不是在属性值更改后立即产生。
在自管理的管理规则所支持的各类事件中,有一类被称作TraceEvent。这类事件是由CallFlow应用产生的,下面将就CallFlow技术做出介绍。







