JMX Monitor主要用于监控MBeanServer注册的MBeans属性值得变化,在属性的值达到阈值的时候发送消息。JMX agent需要实现Monitor功能。
下面看一下例子:
代码1:标准MBean接口1 package test.jmx.monitor;
2
3 public interface CountMBean {
4 public int getCount();
5 }
代码2:标准MBean的实现类 1 package test.jmx.monitor;
2
3 public class Count implements CountMBean{
4 int count = 0;
5
6 Count(int count){
7 this.count = count;
8 }
9
10 @Override
11 public int getCount() {
12 return count;
13 }
14
15 public void addNumber(){
16 count = count + 3;
17 }
18 }
19
代码3:测试类 1 package test.jmx.monitor;
2
3 import javax.management.MBeanServer;
4 import javax.management.MBeanServerFactory;
5 import javax.management.MalformedObjectNameException;
6 import javax.management.Notification;
7 import javax.management.NotificationListener;
8 import javax.management.ObjectName;
9 import javax.management.monitor.CounterMonitor;
10 import javax.management.monitor.Monitor;
11 import javax.management.monitor.MonitorNotification;
12
13 import org.junit.Test;
14
15 public class MonitorTest {
16
17 @Test
18 public void test1CountMonitor() throws Exception{
19 MBeanServer ms = MBeanServerFactory.createMBeanServer();
20
21 final Count count = new Count(0);
22 final ObjectName nameCount = new ObjectName("Count:type=StandardMBean");
23 ms.registerMBean(count, nameCount);
24
25 //这个监听器类主要用于监听一个对象的属性(数值类型)
26 CounterMonitor cMonitor = new CounterMonitor();
27 //被监听的对象
28 cMonitor.addObservedObject(nameCount);
29 //被监听者的属性
30 cMonitor.setObservedAttribute("Count");
31 //阈值为3,超过的话,触发事件
32 cMonitor.setInitThreshold(4);
33 //间隔时间
34 cMonitor.setGranularityPeriod(1000);
35 //接受监控的事件
36 cMonitor.setNotify(true);
37 //监控期间没发现超过一次阈值,那么阈值偏移值往上加 threshold = threshold+offset;
38 cMonitor.setOffset(4);
39 //注册一个Lister,用来监听Monitor所产生的消息(事件)
40 cMonitor.addNotificationListener(new NotificationListener() {
41 @Override
42 public void handleNotification(Notification notification, Object handback) {
43 MonitorNotification n = (MonitorNotification)notification;
44 CounterMonitor monitor = (CounterMonitor)n.getSource();
45 if(MonitorNotification.THRESHOLD_VALUE_EXCEEDED.equals(n.getType())){
46 System.out.println("Count类-"+monitor.getObservedAttribute()+"属性:"+n.getDerivedGauge()
47 +">=了设定的阈值:"+n.getTrigger()+";下个阈值:"+monitor.getThreshold(nameCount));
48 }else{
49 System.out.println(n.getType()+"--"+n);
50 }
51 }
52 },null,null);
53
54 //Monitor本身就是一个标准MBean,而且Monitor也必须被注册到MBeanServer中
55 ObjectName nameMonitor = new ObjectName("CountMonitor:type=Monitor");
56 ms.registerMBean(cMonitor, nameMonitor);
57 //开始监控
58 cMonitor.start();
59
60 for(int i=0;i<5;i++){
61 count.addNumber();
62 Thread.sleep(2000);
63 }
64 Thread.sleep(5000);;
65 }
66
67 }
68
对MBean进行监控,基本有以下几个步骤
1 注册被监控的MBean
2 实例化一个Monitor,如monitor。
3 monitor里添加被监控类,即关联起监控类和被监控类(调用monitor.
addObservedObject(MBean))。4 monitor设置相关属性,如监控间隔时间(setGranularityPeriod(...))、监控的属性(即被监控MBean的一个属性,setObservedAttribute(...),比如例子中的属性"Count",监控会取得这个值,跟其他属性对比,达到了阈值,则触发事件),其他Monitor实现类的相关属性。
5 启动监控(m.start())。
图:MonitorMBean的层次图看下Monitor中主要类:
MonitorMBean
定义了一个JMX监控的开始、结束、加入监控的MBean、设置监控的间隔等
图:MonitorMBean接口Monitor、CountMonitor、GaugeMonitor、StringMonitor
从MonitorMBean的层次图中看出,Monitor实现了MonitorMBean,Monitor作为一个抽象类,实现了大部分功能,包括监控的启动、结束、任务调度,监控的逻辑等。而XXXMonitor作为子类,实现Monitor中的特定方法,即采用了模板方法模式。
参考:http://docs.oracle.com/javase/7/docs/technotes/guides/jmx/JMX_1_4_specification.pdf (JMX规范说明)