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規范說明)