`
iamzhongyong
  • 浏览: 796337 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JMX和MBean以及pojo-mbean学习

 
阅读更多

        最近在看一个开源的Cache框架,里面提到使用JMX来查看Cache的命中率以及响应时间等,于是翻了一些JMX的文章,整理了一下。

    1. 问题:什么是JMX?

    2. 问题:JMX的架构是什么样子的?

    3. 问题:JMX以及Mbean中的 概念都有那些?

    4. 问题:如何编写一个简单的Standard MBean?

    5. 问题:如何编写一个DynamicMBean?

    6. 问题:Open MBean 和Mode MBean是作用是啥?

    7. 问题:按照MBean的规范写,是不是有点繁琐,有没有简单点的办法?

 

    ​    ​问题:什么是JMX?

    ​    ​JMX(java management extensions)java管理程序扩展,是一个为应用程序、设备、系统等植入管理功能的框架。

        JMX使用了最简单的一类javaBean,使用有名的MBean,其内部包含了数据信息,这些信息可能是程序配置信息、模块信息、系统信息、统计信息等。MBean可以操作可读可写的属性、直接操作某些函数。

        

    ​    ​问题:JMX的架构是什么样子的?      

        

 

    ​    ​

    ​    ​问题:JMX使用三层架构,各个层的详细描述是怎么样的?

Probe Level负责资源的检测(获取信息),包含MBeans,通常也叫做Instrumentation Level。

The Agent Level 或者叫做MBean Server,是JMX的核心,连接这个Mbeans和应用程序。

Remote Management Level通过connectors和adaptors来远程操作MBeanServer, Applications可以是大家比较熟悉的控制台,例如JConsole。

    ​   

    ​    ​JMX以及Mbean中的 概念都有那些?

1、MBean

通常是一个java类,他提供接口,可以是这个类具有管理功能。

Standard Mbean是最简单的MBean,他能管理的资源必须定义在接口中,然后MBean必须实现这个接口,命名必须遵守一定的规范。

1
2
3
4
5
6
MBean interface
1、名字必须以MBean结尾
2、必须与签名暴漏属性和操作
MBean implement
1、必须有个名字和接口中"MBean"的前缀相同
2、实现接口中的方法

Dynamic Mbean必须实现DynamicMBean,所有的属性和方法都在运行时定义。

1
2
1、必须实现DynamicMBean接口
2、在实现类中实现DynamicMBean中的方法

2、MBean Server

管理MBean的一个java类,需要向MBean Server中注册一个MBean之后,这个MBean才会具有管理功能,MBeanServer还提供了查询和注解监听器的功能,不同的JMX实现中MBean Server实现也不同。

3、JMX agent

agent是为了管理一些列的MBean而提供的一系列服务。agent可以利用protocal adapters(例如HTTP)和connectors使不同的客户端可以访问MBean。

 

    ​    ​问题:如何编写一个简单的Standard MBean?

1、编写MBean的接口:TestMBean.java

定义了属性的get和set方法以及一个操作方法

1
2
3
4
5
public interface TestMBean {
    public void printHelloWorld();
    public String getName();
    public void setName(String name);
}

2、写一个类实现刚才的MBean接口Test.java

1
2
3
4
5
6
7
8
9
10
11
12
public class Test implements TestMBean {
    private String name;
    public void printHelloWorld() {
        System.out.println(name+",welcome to this world.");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

3、编写一个main函数(将MBean注册到MBeanServer中)Main.java

1
2
3
4
5
6
7
8
9
10
11
12
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class Main {
    public static void main(String[] args) throws Exception{
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        ObjectName name = new ObjectName("agent:name=test");
        Test testMBean = new Test();
        mBeanServer.registerMBean(testMBean, name);
        Thread.sleep(5000000);
    }
}

4、通过JConsole来链接java进程,获取agent信息,通过MBeanServer来操作MBean



 

 

 

    ​    ​问题:如何编写一个DynamicMBean?

1、搞一个类继承DynamicMBean(  TestDynamic.java)

初始化MBeanMeta 信息,包括Attribute和operation

实现Invoke方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.ReflectionException;
public class TestDynamic implements DynamicMBean {
    private String name = "iamzhongyong";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public void printName(){
        System.out.println(name);
    }
    public Object getAttribute(String attribute)
            throws AttributeNotFoundException, MBeanException,
            ReflectionException {
        if(attribute==null){
            throw new AttributeNotFoundException();
        }
        if("name".equalsIgnoreCase(attribute)){
            return getName();
        }
        throw new AttributeNotFoundException();
    }
 
    public void setAttribute(Attribute attribute)
            throws AttributeNotFoundException, InvalidAttributeValueException,
            MBeanException, ReflectionException {
        String name = attribute.getName();
        Object value = attribute.getValue();
        if("name".equalsIgnoreCase(name)){
            this.setName(String.valueOf(value));
            return;
        }
        throw new AttributeNotFoundException();
    }
 
    public AttributeList getAttributes(String[] attributes) {
        return null;
    }
 
    public AttributeList setAttributes(AttributeList attributes) {
        return null;
    }
 
    public Object invoke(String actionName, Object[] params, String[] signature)
            throws MBeanException, ReflectionException {
        if("printName".equals(actionName)){
            printName();
        }
        return null;
    }
 
    public MBeanInfo getMBeanInfo() {
        MBeanAttributeInfo[] dAttributes = new MBeanAttributeInfo[] {
                new MBeanAttributeInfo("name""String""缓存名称"true,  truefalse)};
        MBeanOperationInfo opers[] = {
                new MBeanOperationInfo("printName","print",null,"void",MBeanOperationInfo.ACTION)};
 
        MBeanInfo info = new MBeanInfo(this.getClass().getName(),
                                        "TestDynamic",
                                        dAttributes,
                                        null,
                                        opers,
                                        null);
        return info;
    }
}

2、main函数编写(注册到MBeanServer中)

1
2
3
4
5
6
7
8
9
10
11
12
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class Main {
    public static void main(String[] args) throws Exception{
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        ObjectName name = new ObjectName("agent:name=test");
        TestDynamic testMBean = new TestDynamic();
        mBeanServer.registerMBean(testMBean, name);
        Thread.sleep(5000000);
    }
}

 

 

 

    ​    ​问题:Open MBean 和Mode MBean是作用是啥?

    ​    ​其实这两类也是动态的MBean,OpenMBean和其他MBean不同之处在于公共接口的返回值有所限制,只能是基本类型或者openmbean包内的类型。(可能主要考虑到远端管理系统,可能不具备MBean接口中的特殊的类)

普通的动态的MBean缺少一些管理系统的支持,例如MBean的状态持久化或者日志记录等,因为JMX厂商提供不同的MobleMBean的实现,方便用户进行操作。

使用pojo-mbean来减少MBean繁琐的操作

 

 

 

    ​    ​问题:按照MBean的规范写,是不是有点繁琐,有没有简单点的办法?

有的,基于POJO-MBean来做JMX,通过注解来实现一些繁琐的步骤,让动态MBean不在那么蛋疼。

pojo-mbean提供了一种基于注解来减少繁琐的MBean的方式(http://code.google.com/p/pojo-mbean/)。

pojo-mbean没有依赖任何第三方的包,需要JDK5以上,通过注解标示一个类,是这个类作为MBean,包括属性、操作以及参数等。

版本依赖:

1
2
3
4
5
<dependency>
    <groupId>org.softee</groupId>
    <artifactId>pojo-mbean</artifactId>
    <version>1.1</version>
</dependency>

主要原理:

1、在注册MBeanServer的时候,扫描注解的类文件

2、然后转换MBean的Meta信息,把相关的信息通过反射完成

3、抽象类实现DynamicMBean

实例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import org.softee.management.annotation.Description;
import org.softee.management.annotation.MBean;
import org.softee.management.annotation.ManagedAttribute;
import org.softee.management.annotation.ManagedOperation;
import org.softee.management.annotation.Parameter;
import org.softee.management.helper.MBeanRegistration;
 
 
@MBean(objectName="pojo-agent-test:name=HelloWorld")
@Description("HelloWorld MBean by pojo-mbean")
public class HelloWorld {
 
    private String name ;
 
    private int age;
 
    @ManagedOperation
    @Description("print the name and age")
    public void print(){
        System.out.println("name="+name+",age="+age);
    }
    @ManagedOperation
    @Description("increment the age and then return the new age")
    public int incrementAge(@Parameter("age")int age){
        this.age = this.age+age;
        return this.age;
    }
 
    @ManagedAttribute @Description("about name")
    public String getName() {
        return name;
    }
    @ManagedAttribute
    public void setName(String name) {
        this.name = name;
    }
 
    @ManagedAttribute @Description("about age")
    public int getAge() {
        return age;
    }
    @ManagedAttribute
    public void setAge(int age) {
        this.age = age;
    }
    /**
     * 把MBean注册到MBeanServer中
     * @throws Exception
     */
    public void initMBeanServer() throws Exception{
         new MBeanRegistration(this).register();
    }
 
    public static void main(String[] args) throws Exception{
        HelloWorld a = new HelloWorld();
        a.initMBeanServer();
        Thread.sleep(500000);
    }
}

 

    ​    ​基于此,之后通过MBean来实现一些监控或者管理,就能比较方便了。

 

参考文章:

http://en.wikipedia.org/wiki/Java_Management_Extensions

http://homepages.thm.de/~hg51/Veranstaltungen/Komponenten-11/Folien/components-jmx.pdf

http://my.oschina.net/zhongl/blog/29075

http://www.blogjava.net/heavensay/archive/2012/09/24/386308.html

 

  • 大小: 67.6 KB
  • 大小: 73.2 KB
0
0
分享到:
评论
2 楼 iamzhongyong 2013-11-17  
andye 写道
你看哪个开源Cache框架,还带有JMX功能?

ehcache就有的
1 楼 andye 2013-08-31  
你看哪个开源Cache框架,还带有JMX功能?

相关推荐

Global site tag (gtag.js) - Google Analytics