JMX之监控

使用监控服务,可以观察一个或者多个MBean的之在一段时间内的变化。这个值可以是一个数据类型,也可以是一个比较复杂的数据类型。

监控类型

  • CountMonitor 观察一个Java 整数类型(Byte,Integer,Short,Long)
    • 这个值总是大于等于0
    • 他们只能增加
    • 它们可以翻转,并且在这种情况下,限定模量值
  • GaugeMonitor 观察一个值Java整数类型或者浮点类型行为能够被测量
  • StringMonitor 观察一个String类型的值

所有的监控类型都继承与抽象的Monitor类,定义了通用的属性和操作。每一个监控类同时也是一个标准的MBean,允许通过其他的MBean或者管理应用来进行创建和动态的配置。

CounterMonitor

当观察一个统计值达到或者操作阀值时,统计监控将会发送一个通知。
如图:
11111.jpg

CounterMonitor实例:
maven 依赖

<dependency>  
 <groupId>org.glassfish.external</groupId>  
 <artifactId>opendmk_jdmkrt_jar</artifactId>  
 <version>1.0-b01-ea</version>  
</dependency>

CountMBean.java

public interface CountMBean {  
  int getCount();  
  void incrCount();  
  void computeCount(int number);  
}

Count.java

public class Count implements CountMBean {  

  private AtomicInteger count = new AtomicInteger(0);  

  @Override  
  public int getCount() {  
        return count.get();  
  }  

    @Override  
  public void incrCount() {  
        count.incrementAndGet();  
  }  

    @Override  
  public void computeCount(int number) {  
        count.getAndAdd(number);  
  System.out.println("count : " + count.get());  
  }  
}

CountAgent .java

public class CountAgent {  
    public static void main(String[] args) throws Exception {  
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();  
  Count count = new Count();  
  ObjectName countName = new ObjectName("MyMBean:type=count");  
  server.registerMBean(count, countName);  

  // 监听数值类型  
  CounterMonitor counterMonitor = new CounterMonitor();  
  // 监听对象  
  counterMonitor.addObservedObject(countName);  
  // 监听属性  
  counterMonitor.setObservedAttribute("Count");  
  // 设置初始阀值  
  counterMonitor.setInitThreshold(3);  
  // 设置接受监听  
  counterMonitor.setNotify(true);  
  //监控期间没发现超过一次阈值,那么阈值偏移值往上加 threshold = threshold+offset;  counterMonitor.setOffset(1);  
  // 增加监听器  
  counterMonitor.addNotificationListener(new NotificationListener() {  
            @Override  
  public void handleNotification(Notification notification, Object handback) {  
                MonitorNotification monitorNotification = (MonitorNotification) notification;  
  CounterMonitor counterMonitor1 = (CounterMonitor) monitorNotification.getSource();  
 if (MonitorNotification.THRESHOLD_VALUE_EXCEEDED.equals(monitorNotification.getType())) {  
                    System.out.println("Count Class: "+ monitorNotification.getObservedAttribute() + " :" + monitorNotification.getDerivedGauge() + "  threshold: " + counterMonitor1.getInitThreshold());  
  } else {  
                    System.out.println(monitorNotification.getType());  
  }  
            }  
        }, null, null);  
  // monitor 也是一个MBean,也需要注册到 server 上  
  ObjectName nameMonitor = new ObjectName("CountMonitor:type=Monitor");  
  server.registerMBean(counterMonitor, nameMonitor);  

  // 增加html adapter  
  HtmlAdaptorServer htmlAdaptorServer = new HtmlAdaptorServer();  
  ObjectName adapterName= new ObjectName("CountAgent:name=htmladapter,port=8082");  

  server.registerMBean(htmlAdaptorServer, adapterName);  
  counterMonitor.start();  
  htmlAdaptorServer.start();  
  System.out.println("server start on 8082");  
  }  
}

通过浏览器访问 localhost:8082, 通过操作incrCount,监控并且触发监听。
MonitorNotification在一下情况,将会触发通知:

  • 检查监控触发的条件
  • 观察的属性遇到了错误

GaugeMonitor

测量监控器观察一个数值类型的值的行为作为测量标准。当测量值在阀值左右波动,滞后机制将会避免重复发送通知。它的这种能提供了2个值,一个高阀值和一个低阀值。
如图:
22222.jpg

实例代码:

public class GaugeAgent {  

    public static void main(String[] args) throws Exception {  
      MBeanServer server = ManagementFactory.getPlatformMBeanServer();  
      Count count = new Count();  
      ObjectName countName = new ObjectName("count:type=MyCount");  
      server.registerMBean(count, countName);  
      GaugeMonitor gaugeMonitor = new GaugeMonitor();  
      gaugeMonitor.addObservedObject(countName);  
      gaugeMonitor.setObservedAttribute("Count");  
      gaugeMonitor.setThresholds(5, 1);  
      gaugeMonitor.setNotifyHigh(true);  
      gaugeMonitor.setNotifyLow(true);  
      gaugeMonitor.setGranularityPeriod(2000);  
      gaugeMonitor.addNotificationListener(new NotificationListener() {  
                @Override  
      public void handleNotification(Notification notification, Object handback) {  
                    MonitorNotification monitorNotification = (MonitorNotification) notification;  
     if (MonitorNotification.THRESHOLD_HIGH_VALUE_EXCEEDED.equals(monitorNotification.getType())) {  
                        System.out.println("up " + monitorNotification.getDerivedGauge());  
      }  
                    if (MonitorNotification.THRESHOLD_LOW_VALUE_EXCEEDED.equals(monitorNotification.getType())) {  
                        System.out.println("down " + monitorNotification.getDerivedGauge());  
      }  
                }  
            }, null, null);  

      ObjectName nameMonitor = new ObjectName("GaugeMonitor:type=Monitor");  
      server.registerMBean(gaugeMonitor, nameMonitor);  

      // 增加html adapter  
      HtmlAdaptorServer htmlAdaptorServer = new HtmlAdaptorServer();  
      ObjectName adapterName = new ObjectName("CountAgent:name=htmladapter,port=8082");  

      server.registerMBean(htmlAdaptorServer, adapterName);  
      gaugeMonitor.start();  
      htmlAdaptorServer.start();  

      System.out.println("server start on 8082");  
  }  
}

StringMonitor

string监控器主要是观察一个string对象,string 监控器配置了一个 string的对象,比较值是否发生改变,触发的2种条件:

  • 测量string的比较匹配,如果 NotifyMatch 为 true,将会发送通知。
  • 如果测量的值不同于字符串比较的值,如果 NotifyDiffer为true,将会发送通知。
    如图:
    33333.jpg

实例代码:

public class StringAgent {  

    public static void main(String[] args) throws Exception{  
          MBeanServer server = ManagementFactory.getPlatformMBeanServer();  
          Str str = new Str();  
          ObjectName strName = new ObjectName("str:type=MyStr");  
          server.registerMBean(str, strName);  

          StringMonitor stringMonitor = new StringMonitor();  
          stringMonitor.addObservedObject(strName);  
          stringMonitor.setNotifyDiffer(true);  
          stringMonitor.setNotifyMatch(true);  
          stringMonitor.setStringToCompare("XYZ");  
          stringMonitor.setObservedAttribute("Str");  
          stringMonitor.setGranularityPeriod(2000);  
          stringMonitor.addNotificationListener(new NotificationListener() {  
                    @Override  
          public void handleNotification(Notification notification, Object handback) {  
                        MonitorNotification monitorNotification = (MonitorNotification)notification;  
         if (stringMonitor.getNotifyDiffer() || stringMonitor.getNotifyMatch()) {  
                            System.out.println(monitorNotification.getObservedAttribute()+", "  
          +monitorNotification.getDerivedGauge()+","  
          +monitorNotification.getSource()+", "+monitorNotification.getType());  
          }  
                    }  
                }, null, null);  

          ObjectName nameMonitor = new ObjectName("StringMonitor:type=Monitor");  
          server.registerMBean(stringMonitor, nameMonitor);  

          // 增加html adapter  
          HtmlAdaptorServer htmlAdaptorServer = new HtmlAdaptorServer();  
          ObjectName adapterName = new ObjectName("StringAgent:name=htmladapter,port=8082");  

          server.registerMBean(htmlAdaptorServer, adapterName);  
          stringMonitor.start();  
          htmlAdaptorServer.start();  

          System.out.println("server start on 8082");  
  }  
}
添加新评论