二、JMX官方指导文档 之 介绍MBeans

Lesson: Introducing MBeans

这节课介绍了JMX API的基本概念,即被管理的Bean或者MBeans。
一个MBean是一个被管理的Java对象,和JavaBean组件相似遵循一系列之后定义的JMX规范。一个MBean可以描述一个设备、应用或者其他被管理的资源。MBeans假定    一个被管理的接口包含下面的部分:
一些可读或者可写的属性,或者他们两者。
一些可被调用的操作
一个自描述
管理接口不改变MBean实例的声明, 但是MBean可以在预定义的事件发生的时候发送通知。
JMX规范定义了五种类型的MBean:
  • Standard MBeans
  • Dynamic MBeans
  • Open MBeans
  • Model MBeans
  • MXBeans
下面的例子仅仅使用了最简单的MBean,标准MBeans和MXBeans。


Standard MBeans

这节将介绍一个简单的例子,标准MBean。
可以通过写一个Java接口 SomethingMBean来定义一个标准的MBean,它的实现类是Something。接口中定义的每个方法要么是MBean的属性要么是它的操作方法。默认每一个方法定义一个操作。属性和操作是遵循确定设计模式的方法。一个标准的MBean由一个MBean接口和一个类组成。MBean接口列出了所有要暴露的属性和方法。实现了这个接口的类提供了对资源功能的描述。
下面写了一个标准MBean的例子和简单的JMX代理来管理MBean。
MBean Interface
基础的MBean接口:
package com.example; 
 
public interface HelloMBean { 
 
    public void sayHello(); 
    public int add(int x, int y); 
    
    public String getName(); 
     
    public int getCacheSize(); 
    public void setCacheSize(int size); 

约定MBean接口以实现它的类的名字加上MBean命名。这样说的话,这个接口叫做HelloMBean。下节的Hello类实现了这个接口。
依据JMX规范,MBean接口包含可读属性、可写属性的名字和类型。根据这些操作可以调用应用中被管理的MBean。HelloMBean接口有两个操作add()和sayHello()。
HelloMBean声明了两个属性: Name是只读的字符串,CacheSzie是一个可读可写的整形。通过定义getter和setter来让远程的管理程序改变这个值。JMX规范定义:getter方法是一个有返回值的公共方法并且方法名以get开始。getter确保这个属性值可以被远程管理读取,这个类型是返回对象的类型。setter是一个带单个参数的公共方法,方法名以set开始。setter确保管理器可以赋一个新值给这个属性,类型和属性的类型一致。
这些操作和属性的实现在接下来的章节。


MBean Implementation

实现了HelloMBean的Hello类如下:
package com.example; 
 
public class Hello ... 
    implements HelloMBean { 
    public void sayHello() { 
        System.out.println("hello, world"); 
    } 
     
    public int add(int x, int y) { 
        return x + y; 
    } 
     
    public String getName() { 
        return this.name; 
    }  
     
    public int getCacheSize() { 
        return this.cacheSize; 
    } 
     
    public synchronized void setCacheSize(int size) {
        ...
    
        this.cacheSize = size; 
        System.out.println("Cache size now " + this.cacheSize); 
    } 
    ...
     
    private final String name = "Reginald"; 
    private int cacheSize = DEFAULT_CACHE_SIZE; 
    private static final int  DEFAULT_CACHE_SIZE = 200; 
}
Hello类提供了定义在HelloMBean中的属性和操作。sayHello()和add()操作非常简单,但是你需要的真实的操作可能是简单的或者复杂的。
Name属性的get方法和CacheSize属性的get、set方法也被定义完成。在这个例子中, Name属性不会被改变。然而,这个属性可能被运行的资源改变。例如,属性可能代表统计数字,如:运行时间和内存使用情况。但是这里Name仅仅是Reginald。
可以调用setCacheSize方法去改变CacheSize的200默认值。在实际的环境中,CacheSize可能还需要做一些其他的操作,例如:释放对象和申请新的对象。这个例子打印了一些信息去表明缓存大小已经改变。然而可以使用复杂的操作来替代简单的调用println()方法。
在下面的章节中你可以使用Hello MBean和定义的接口来管理这个资源。


Creating a JMX Agent to Manage a Resource

一旦资源已经使用MBeans描述完毕,就可以使用JMX代理管理这个资源。
JMX代理的核心组件是MBean server。MBean server是一个管理被注册的MBean对象的服务器。JMX代理包括一些被管理的MBean夫妇。看关于MBeanServer的API文档,然后看下面的实现:
Main类描述了一个基本的JMX代理:
package com.example; 
 
import java.lang.management.*; 
import javax.management.*; 
 
public class Main { 
 
    public static void main(String[] args) 
        throws Exception { 
     
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
        ObjectName name = new ObjectName("com.example:type=Hello"); 
        Hello mbean = new Hello(); 
        mbs.registerMBean(mbean, name); 
          
        ...
     
        System.out.println("Waiting forever..."); 
        Thread.sleep(Long.MAX_VALUE); 
    } 



Main通过调用 java.lang.management.ManagementFactory的getPlatformMBeanServer() 创建实例化了一个平台MBean server。如果MBean Server还没有被平台创建, getPlatformMBeanServer()会调用MBeanServerFactory.createMBeanServer()的方法去自动创建一个。Main中的MBean server实例叫做mbs.
接下来定义了要创建的MBean对象的对象名字。每一个JMX MBean必须有一个对象名字。这个对象名字是JMX类ObjectName的实例并且必须遵循JMX规范定义的一些语法。即对象名称必须包含域和键属性列表。Main中定义的对象名字的域是com.example(MBean存在的包名)。此外,键-值对声明了这个对象是Hello类型。
一个叫做mBean的Hello对象被创建。这个叫做mBean的Hello对象然后被 MBeanServer.registerMBean()方法注册进了mbs,它需要一个对象和一个对象名字参数。
当Hello MBean被注册进MBean server,Main开始简单的等待Hello的管理操作。在这个例子中,这些管理系统通过调用sayHello()和add()和属性的getter setter来操作被管理的资源。


Running the Standard MBean Example

已经写完了这个例子,你现在可以运行他了。在这个例子中,JConsole被用于连接这个MBean。
按下面的步骤运行:
1.打包你的JMX API例子成jmx_examples.zip,然后放到工作目录。
2.解压这个例子,使用终端窗口命令:
unzip jmx_examples.zip
3.在你的工作目录编译它:
javac com/example/*.java
4.如果你使用的是jdk1.6及以后版本,运行Main的应用:
java com.example.Main
否则使用:
java -Dcom.sun.management.jmxremote example.Main
5.在新的终端窗口中开启JConsole
jconsole
新连接对话框打开后,然后连接。
6. 在新的连接对话框中选择 com.example.Main 然后点击连接。
关于当前平台的概述被打开了
7. 选中MBeans标签页
这个面板展示了当前所有在MBean中注册的MBeans
8. 在左侧的面板中展开 com.example的MBean树。
你可以看到Main中的Hello已经被注册。如果你点击Hello,你讲看到相关的属性和操作节点。
9. 展开Hello MBean的属性节点
定义在Hello中的属性被展示
10. 改变CacheSize的值为150。
  在Main的命令行下你可以看到值已经被改变。
11. 展开Hello的操作节点
Hello MBean的sayHello()和add()操作也是可用的。
12. 点击sayhello按钮调用sayHello()
一个控制台对话框将展示你已经调用成功。"hello, world"信息将在Main的终端窗口展示。
13. 提供两个整形参数然后调用add()
这个结果将在JConsole对话框中展示
14. 关闭JConsole退出。


MXBeans

这一章节演示了一种特殊的MBean,叫做MXBeans。
MXBean是一种预定义了一些数据类型的MBean。使用这种方法可以让你的MBean对所有的客户端可用,包括远程客户端,即使这个客户端没有你MBean的访问模型类。MXBeans提供了一个方便的方法把相关的值收集到一起而不用客户端做一些特殊的配置。
和标准的MBeans一样的方法,写一个Java接口SomethingMXBean然后弄一个类实现它。但是不像标准的MBeans,MXBeans不需要这个类命名为Something。接口中定义的每一个方法可能是MXBean类中的属性或者操作。 @MXBean注解也可以用来标记Java接口,代替使用MXBean后缀命名。
MXBean存在于J2SE 5.0的java.lang.management包中。然而用户也可以定义自己的MXBeans然后添加到java.lang.management中。
MXBeans背后的主要思想是类型,例如:java.lang.management.MemoryUsage 在这种情况下java.lang.management.MemoryMXBean被映射到一个标准类型的集合,也是javax.management.openmbean包下的开发类型。MXBean规范指定了严格的映射规则。然而,总的原则是简单类型如整形和字符串类型保持不变,而复杂的类型例如MemoryUsage被映射成标准的类型CompositeDataSupport。
jmx_examples.zip中的例子包含了下面一些文件:
QueueSamplerMXBean接口
QueueSampler实现类实现了MXBean接口
QueueSample中的getQueueSample()方法返回了MXBean接口。
Main,启动运行这个例子的入口
MXBean例子使用这些类完成了如下的操作:
定义了一个简单的MXBean来管理 Queue<String>类型的资源
在MXBean中声明了一个getter,getQueueSample,调用的时候返回了QueueSample的一个队列快照还有下面的值:
快照的时间
队列的大小
此时队列的头
在MBean server上面注册MXBean。


MXBean Interface

下面的例子展示了 QueueSamplerMXBean接口:
package com.example; 
 
public interface QueueSamplerMXBean { 
    public QueueSample getQueueSample(); 
    public void clearQueue(); 

注意,你声明了一个MXBean接口和标准的MBean接口一样的方法。QueueSamplerMXBean接口声明了一个getter,getQueueSample和一个clearQueue操作。


Defining MXBean Operations

QueueSampler 中声明的操作如下面所示:
package com.example; 
 
import java.util.Date; 
import java.util.Queue; 
 
public class QueueSampler 
               implements QueueSamplerMXBean { 
    
   private Queue<String> queue; 
        
   public QueueSampler (Queue<String> queue) { 
       this.queue = queue; 
   } 
        
   public QueueSample getQueueSample() { 
       synchronized (queue) { 
           return new QueueSample(new Date(), 
                          queue.size(), queue.peek()); 
       } 
   } 
        
   public void clearQueue() { 
       synchronized (queue) { 
           queue.clear(); 
       } 
   } 

QueueSampler定义了MXBean接口中声明的getQueueSample()和clearQueue() 方法。getQueueSample()返回了一个使用 java.util.Queue的peek()、size()和java.util.Date构造的QueueSample实例
Defining the Java Type Returned by the MXBean Interface
QueueSample类是这样的:
package com.example; 
 
import java.beans.ConstructorProperties; 
import java.util.Date; 
 
public class QueueSample { 
    
   private final Date date; 
   private final int size; 
   private final String head; 
        
   @ConstructorProperties({"date", "size", "head"}) 
   public QueueSample(Date date, int size, 
                       String head) { 
       this.date = date; 
       this.size = size; 
       this.head = head; 
   } 
        
   public Date getDate() { 
       return date; 
   } 
        
   public int getSize() { 
       return size; 
   } 
        
   public String getHead() { 
       return head; 
   } 
}   


MXBean框架调用QueueSample的getter去转换成一个复合数据(CompositeData)并且使用@ConstructorProperties注解从复合数据中重建一个QueueSample实例。


Creating and Registering the MXBean in the MBean Server

到目前为止我们已经定义了一个MXBean接口和一个类实现了它。接下来MXBean必须被创建注册到MBean server。这些动作在Main中执行。
package com.example; 
 
import java.lang.management.ManagementFactory; 
import java.util.Queue; 
import java.util.concurrent.ArrayBlockingQueue; 
import javax.management.MBeanServer; 
import javax.management.ObjectName; 
 
public class Main { 
 
   public static void main(String[] args) throws Exception { 
       MBeanServer mbs = 
           ManagementFactory.getPlatformMBeanServer(); 
               
       ...  
       ObjectName mxbeanName = new ObjectName("com.example:type=QueueSampler");
       
       Queue<String> queue = new ArrayBlockingQueue<String>(10);
       queue.add("Request-1");
       queue.add("Request-2");
       queue.add("Request-3");
       QueueSampler mxbean = new QueueSampler(queue);
       
       mbs.registerMBean(mxbean, mxbeanName);
                
       System.out.println("Waiting..."); 
       Thread.sleep(Long.MAX_VALUE); 
   } 

Main中主要干了这些事:
获取一个平台MBean server。
创建一个QueueSampler对象名字。
为QueueSampler创建一个Queue实例。
赋给QueueSampler。
注册这个MXBean给MBean server,和标准MBean一样的方法。


Running the MXBean Example

MXBean例子使用了标准MBeans章节的jmx_examples.zip。这个例子运行在jdk6及之后的平台, 下面是运行步骤:
1. 如果你还没有代码,保存jmx_examples.zip到工作目录。
2.在终端窗口中输入以下命令:
unzip jmx_examples.zip
3.编译work_dir下的类
javac com/example/*.java
4.启动Main应用。
java com.example.Main
5.在同一台电脑上开启JConsole,这个新连接窗口显示出来,你运行的JMX代理将会在列表中展示出来。
jconsole
6.在新连接窗口中选择com.example.Main然后连接。
关于这个平台的概述被展示出来了
7.点击MBeans 标签
这个面板展示了当前MBean server注册的MBeans
8.展开左边的com.example MBean树。
你将看到Main创建、注册的QueueSampler MBean。如果你点击QueueSampler 你会看到它关联的属性和操作。
9.展开属性节点
你会看到QueueSample 属性出现在右边的面板,有一个值:javax.management.openmbean.CompositeDataSupport.
10.双击CompositeDataSupport
你将看到QueueSample有值: date,head和size。因为MXBean框架已经转换QueueSample 实例为CompositeData。如果你定义QueueSampler 作为一个标准的MBean而不是MXBean,那么JConsole将找不到QueueSample 类,因为它不在类路径中。如果QueueSampler 被注册成标准MBean,那么你在检索QueueSample 属性的时候会收到一个ClassNotFoundException。实际上JConsoel发现QueueSampler 演示了如何通过JMX客户端如JConsole如何连接到JMX代理。
11.展开操作节点
调用clearQueue操作。
12.点击clearQueue按钮
方法调用成功的信息将会被展示
13.再一次展开属性按钮然后双击CompositeDataSupport 值
head和size值已经被重置
14.关闭JConsole



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值