JMX和MBean以及pojo-mbean學習

最近在看一個開源的Cache框架,裏面提到使用JMX來查看Cache的命中率以及響應時間等,因而翻了一些JMX的文章,整理了一下。 html

    1. 問題:什麼是JMX? java

    2. 問題:JMX的架構是什麼樣子的? 緩存

    3. 問題:JMX以及Mbean中的 概念都有那些? 架構

    4. 問題:如何編寫一個簡單的Standard MBean? 框架

    5. 問題:如何編寫一個DynamicMBean? 函數

    6. 問題:Open MBean 和Mode MBean是做用是啥? this

    7. 問題:按照MBean的規範寫,是否是有點繁瑣,有沒有簡單點的辦法? google

 

        問題:什麼是JMX? spa

        JMX(java management extensions)java管理程序擴展,是一個爲應用程序、設備、系統等植入管理功能的框架。 .net

        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中的 概念都有那些?

一、MBean

一般是一個java類,他提供接口,能夠是這個類具備管理功能。

Standard Mbean是最簡單的MBean,他能管理的資源必須定義在接口中,而後MBean必須實現這個接口,命名必須遵照必定的規範。

1
2
3
4
5
6
MBean interface:
一、名字必須以MBean結尾
二、必須與簽名暴漏屬性和操做
MBean implement
一、必須有個名字和接口中"MBean"的前綴相同
二、實現接口中的方法

Dynamic Mbean必須實現DynamicMBean,全部的屬性和方法都在運行時定義。

1
2
一、必須實現DynamicMBean接口
二、在實現類中實現DynamicMBean中的方法

二、MBean Server

管理MBean的一個java類,須要向MBean Server中註冊一個MBean以後,這個MBean纔會具備管理功能,MBeanServer還提供了查詢和註解監聽器的功能,不一樣的JMX實現中MBean Server實現也不一樣。

三、JMX agent

agent是爲了管理一些列的MBean而提供的一系列服務。agent能夠利用protocal adapters(例如HTTP)和connectors使不一樣的客戶端能夠訪問MBean。

 

        問題:如何編寫一個簡單的Standard MBean?

一、編寫MBean的接口:TestMBean.java

定義了屬性的get和set方法以及一個操做方法

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

二、寫一個類實現剛纔的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;
     }
}

三、編寫一個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 );
     }
}

四、經過JConsole來連接java進程,獲取agent信息,經過MBeanServer來操做MBean



 

 

 

        問題:如何編寫一個DynamicMBean?

一、搞一個類繼承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;
     }
}

二、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>

主要原理:

一、在註冊MBeanServer的時候,掃描註解的類文件

二、而後轉換MBean的Meta信息,把相關的信息經過反射完成

三、抽象類實現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

相關文章
相關標籤/搜索