Java SE 6 新特性: JMX 與系統管理(2)

 

Java SE 6 新特性: JMX 與系統管理(2)

 

  這裏的 ServerMonitorBean 又是怎麼回事呢?MXBean 規定了標準 MBean 也要實現一個接口,所有向外界公開的方法都要在這個接口中聲明。否則,管理系統就不能從中獲得相應的信息。此外,該接口的名字也有一定的規範:即在標準 MBean 類名之後加上“MBean”後綴。若 MBean 的類名叫做 MBeansName 的話,對應的接口就要叫做 MBeansNameMBean。

  對於管理系統來說,這些在 MBean 中公開的方法,最終會被 JMX 轉化成屬性(Attribute)、監聽(Listener)和調用(Invoke)的概念。如果讀者對 Java Bean 有一些瞭解的話,不難看出,>public long getUpTime() 對應了 Bean 中的一個稱爲“upTime”的只讀屬性。

  下面我們就看一個模擬管理系統的例子:

package standardbeans; 
import javax.management.MBeanServer; 
import javax.management.MBeanServerFactory; 
import javax.management.ObjectName; 
public class Main { 
    private static ObjectName objectName ; 
    private static MBeanServer mBeanServer; 
    public static void main(String[] args) throws Exception{ 
        init(); 
        manage();                
    } 
    private static void init() throws Exception{ 
        ServerImpl serverImpl = new ServerImpl(); 
        ServerMonitor serverMonitor = new ServerMonitor(serverImpl); 
        mBeanServer = MBeanServerFactory.createMBeanServer(); 
        objectName = new ObjectName("objectName:id=ServerMonitor1"); 
        mBeanServer.registerMBean(serverMonitor,objectName);   
    } 
    private static void manage() throws Exception{ 
        Long upTime = (Long) mBeanServer.getAttribute(objectName, 
        "upTime"); 
        System.out.println(upTime); 
    }  
} 

  JMX 的核心是 MBServer。Java SE 已經提供了一個默認實現,可以通過 MBServerFactory.createMBeanServer() 獲得。每個資源監控者(MBean)一般都會有名稱(ObjectName), 登記在 MBServer 內部的一個 Repository 中。注意,這個 ObjectName 對於每一個 MBServer 必須是唯一的,只能對應於一個 MBean。(讀者有興趣的話,可以試着再給 mBeanServer 註冊一個同名的 objectName,看看會怎麼樣。) 上述例子是在 >init() 方法中完成向 MBeanServer 註冊工作的。

  在管理過程中,管理系統並不與資源或者 SubAgent 直接打交道,也就是說,這裏不會直接引用到 MBean。而是通過 MBeanServer 的 >getAttribute 方法取得對應 MBean 的屬性的。

  動態 MBean

  但是對於很多已有的 SubAgent 實現,其 Coding Convention 並不符合標準 MBean 的要求。重構所有這些 SubAgent 以符合標準 MBean 標準既費力也不實際。JMX 中給出了動態(Dynamic) MBean 的概念,MBServer 不再依據 Coding Convention 而是直接查詢動態 MBean 給出的元數據(meta data)以獲得 MBean 的對外接口。

package dynamicbeans; 

import javax.management.*; 
import java.lang.reflect.*; 
public class ServerMonitor implements DynamicMBean { 
  
    private final ServerImpl target;     
    private MBeanInfo mBeanInfo;     
         
    public ServerMonitor(ServerImpl target){ 
        this.target = target; 
    } 
     
    //實現獲取被管理的 ServerImpl 的 upTime 
    public long upTime(){ 
        return System.currentTimeMillis() - target.startTime; 
    } 

 //javax.management.MBeanServer 會通過查詢 getAttribute("Uptime") 獲得 "Uptime" 屬性值 
    public Object getAttribute(String attribute) throws AttributeNotFoundException,  
  MBeanException, ReflectionException { 
        if(attribute.equals("UpTime")){ 
            return upTime(); 
        } 
        return null; 
    } 
  
 //給出 ServerMonitor 的元信息。   
    public MBeanInfo getMBeanInfo() { 
        if (mBeanInfo == null) { 
            try { 
                Class cls = this.getClass(); 
                //用反射獲得 "upTime" 屬性的讀方法 
                Method readMethod = cls.getMethod("upTime", new Class[0]);  
                //用反射獲得構造方法 
                Constructor constructor = cls.getConstructor(new Class[] 
     {ServerImpl.class}); 
                //關於 "upTime" 屬性的元信息:名稱爲 UpTime,只讀屬性(沒有寫方法)。 
                MBeanAttributeInfo upTimeMBeanAttributeInfo = new MBeanAttributeInfo( 
                        "UpTime", "The time span since server start", 
                        readMethod, null); 
                //關於構造函數的元信息 
                MBeanConstructorInfo mBeanConstructorInfo = new MBeanConstructorInfo( 
                        "Constructor for ServerMonitor", constructor); 
                //ServerMonitor 的元信息,爲了簡單起見,在這個例子裏, 
                //沒有提供 invocation 以及 listener 方面的元信息  
                mBeanInfo = new MBeanInfo(cls.getName(), 
                        "Monitor that controls the server", 
                        new MBeanAttributeInfo[] { upTimeMBeanAttributeInfo }, 
                        new MBeanConstructorInfo[] { mBeanConstructorInfo }, 
                        null, null);                 
            } catch (Exception e) { 
                throw new Error(e); 
            } 

        } 
        return mBeanInfo; 
    } 

    public AttributeList getAttributes(String[] arg0) {         
        return null; 
    } 
         
    public Object invoke(String arg0, Object[] arg1, String[] arg2)  
  throws MBeanException,  
  ReflectionException {         
        return null; 
    } 

    public void setAttribute(Attribute arg0) throws AttributeNotFoundException,  
  InvalidAttributeValueException, MBeanException, ReflectionException { 
        return;         
    } 

    public AttributeList setAttributes(AttributeList arg0) {         
        return null; 
    }    
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章