JMX和MBean以及pojombean学习

编程

最近在看一个开源的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 ,   true ,  false )};

         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

以上是 JMX和MBean以及pojombean学习 的全部内容, 来源链接: utcz.com/z/511113.html

回到顶部