利用自訂 MBean 延伸 WebSphere Application Server 管理系統

您可以在一個 WebSphere 程序中,提供和登錄新的 Java™ Management Extensions (JMX) MBean(請參閱「JMX 1.x 規格」,以取得詳細資料)來延伸 WebSphere® Application Server 管理系統。

關於這項作業

JMX MBean 代表特定邏輯片段的管理介面。 標準產品基礎架構中所有受管理的資源都是以 JMX MBean 來代表。 您可以利用很多方法來建立您自己的 MBean,並將它們登錄在任何 WebSphere 程序所執行的 JMX MBeanServer 中。 如需相關資訊,請參閱 MBean Java 應用程式設計介面 (API) 文件。在這個資訊中心,請按一下參照 > MBean 介面

程序

  1. 建立自訂 JMX MBean。

    當建立 MBean 來延伸產品管理系統時,有一些替代方案可供您選取。 您可以使用另一個應用程式的任何現有的 JMX MBean。 在產品程序中,您可以在 WebSphere Application Server 環境以外的 JMX MBean 伺服器中登錄您測試的任何 MBean,包括標準 MBean、動態 MBean、開放式 MBean 和模型 MBean。

    除了任何現有 JMX MBean 以及在產品環境之外編寫及測試的 JMX MBean 之外,您還可以使用 WebSphere 提供的特殊分散式延伸並建立 WebSphere ExtensionMBean 提供者。 這個替代方案能夠更好地整合產品管理系統的所有分散式功能。 ExtensionMBean 提供者隱含著您提供了一份 XML 檔,其中含有基於產品提供之 DTD 的 MBean 描述子。 這個描述子會將 MBean 支援的所有屬性、作業以及通知告訴 WebSphere 系統。 有了這個資訊,WebSphere 系統便能夠將遠端要求遞送至您的 MBean,並登錄遠端接聽器來接收您的 MBean 事件通知。

    所有內部 WebSphere MBean 都遵循「模型 MBean」型樣。 Pure Java 類別會提供管理功能的實際邏輯,而 WebSphere MBeanFactory 類別會從 XML MBean 描述子讀取這些功能的說明,並建立符合這個描述子的 ModelMBean 的實例。 這個 ModelMBean 實例連結您的 Java 類別,且登錄在與您的類別執行於相同程序的 MBeanServer 中。 現在,任何 WebSphere Application Server 管理用戶端都可以透過為了代表您的 Java 程式碼而建立及登錄的 ModelMBean 來呼叫這個程式碼。

    [z/OS]WebSphere Application Server 分散式平台和 WebSphere Application Server for z/OS® 平台兩者上執行的使用者 MBean 可能會需要特殊編碼,才能在 z/OS 多程序模型中正常運作。 在每個應用程式伺服器都執行於單一 Java 虛擬機器 (JVM) 的分散式平台上,只有一個 MBean 伺服器。 這個 MBean 伺服器控制著所有在這個應用程式伺服器內登錄的 MBean。 在 z/OS 平台上,存在一個控制程序,還有一個服務者程序組成的聯合,每個程序各有自己的 MBean 伺服器。 控制程序有自己的 MBean Proxy 伺服器,用來在服務者程序之間分配要求。 請參閱「JMX MBean 多程序模型要求流程」的詳細討論。

  2. 選擇性地定義明確的 MBean 安全原則。

    如果您沒有定義 MBean 安全原則,產品會使用預設安全原則

  3. 登錄新的 MBean。 您可以利用多種方法來登錄 MBean。

    您可以向 WebSphere Application Server 管理服務登錄您的 MBean。

    您可以在 WebSphere Application Server 程序中,向 MBeanServer 登錄您的 MBean。 下列清單按照喜好設定順序來說明可用的選項:
    • 透過 MBeanFactory 類別。如果您想要實現與 WebSphere Application Server 系統最大可能的整合,請利用 MBeanFactory 類別,透過 MBeanFactory 類別的 activateMBean 和 deactivateMBean 方法來管理 MBean 的生命週期。 當使用這些方法時,請提供一個 RuntimeCollaborator 抽象超類別的子類別和一個 XML MBean 描述子檔案。 在這個方式之下,您會提供一個實作 MBean 描述子所定義之管理介面的純正 Java 類別。 MBeanFactory 類別會建立實際的 ModelMBean,且會代表您向產品管理系統登錄這個 ModelMBean。

      登錄模型 MBean 時,建議使用這個選項。

    • 使用 JMXManageable 和 CustomService 介面。您可以實作 CustomService 介面(這個介面也實作 JMXManageable 介面),以便更加容易進行與 WebSphere 管理整合的程序。 在這個方式之下,您可以避免提供 RuntimeCollaborator。 當起始設定 CustomService 介面時,WebSphere MBeanFactory 類別會讀取 XML MBean 描述子檔案,且會自動建立一個 MBean,並將它連結及登錄到您的 CustomService 介面。 呼叫 CustomService 的關閉方法之後,產品系統會自動取消啟動 MBean。
    • 透過 AdminService 介面。您可以在 AdminService 介面上呼叫 registerMBean() 方法,在進行適當的安全檢查之後,會將這個呼叫委派給程序的基礎 MBeanServer。 您可以利用 AdminServiceFactory 類別的 getAdminService() 方法來取得對 AdminService 的參照。

      登錄標準、動態和開放式 MBean 時,建議使用這個選項。 請實作 UserCollaborator 類別來使用 MBean,並跨越分散式平台及 z/OS 平台來提供它們一致的支援層次。

      [z/OS]如果是 z/OS 平台,在伺服器之外看不到在 AdminService 介面上透過 registerMBean() 方法來登錄的 MBean,只有從 MBean 登錄所在的服務者程序,才能呼叫它。

    • 直接取得 MBeanServer 實例。您可以呼叫 MBeanFactory 類別的 getMBeanServer() 方法來取得對執行於任何產品程序之 JMX MBeanServer 實例的直接參照。 呼叫 AdminService 介面的 getMBeanFactory() 方法可讓您取得對 MBeanFactory 類別的參照。

      直接向 MBean伺服器登錄自訂 MBean 時,依預設,會用 Cell、節點和程序名稱金鑰來加強 MBean 物件名稱。 這個登錄可讓 MBean 參與管理系統的分散式特性。 您可以設定 com.ibm.websphere.mbeans.disableRouting 自訂內容來關閉這個預設行為。

      請參閱管理服務自訂內容,以取得如何設定及使用 com.ibm.websphere.mbeans.disableRouting 自訂內容的相關資訊。

結果

不論用來建立及登錄 MBean 的方法為何,您都必須為新的 MBean 程式碼設定適當的 Java 2 安全許可權。 WebSphere AdminService 和 MBeanServer 受到 Java 2 安全許可權的嚴格保護,如果您沒有將基本許可權明確授予程式碼,當您試圖呼叫這些類別的方法時,系統會擲出安全異常狀況。 如果您將 MBean 當作應用程式的一部分來提供,您可以在作為應用程式 meta 資料的一部分而提供的 was.policy 檔中設定許可權。 如果您在使用 CustomService 介面或未作為應用程式而交付的其他程式碼,您可以編輯節點配置中的 library.policy 檔,您甚至可以為特定安裝來編輯 properties 目錄中的 server.policy 檔。

[z/OS]

範例:SampleStateMBean MBean

MBeanDescriptor

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MBean SYSTEM "MbeanDescriptor.dtd">
<MBean type="SampleStateMBean"
  aggregationHandlerClass="com.ibm.ws390.sample.SampleStateAggregationHandler"
  eventHandlerClass="com.ibm.ws390.sample.SampleStateEventHandler"
  invocationHandlerClass="com.ibm.ws390.sample.SampleStateInvocationHandler"
  stateObjectClass="com.ibm.ws390.sample.SampleState"
  version="6.0"
  platform="dynamicproxy"
  description="Sample State MBean for the documentation example.">

  <attribute description="The name of the MBean."
    getMethod="getMBeanName" name="mbeanName" type="java.lang.String"
    proxyInvokeType="unicall"/>
  <attribute description="The state of the MBean." name="state"
    getMethod="getState" setMethod="setState" type="java.lang.String"
    proxyInvokeType="multicall" proxySetterInvokeType="multicall"/>
  <operation
    description="Initialize the State MBean."
    impact="ACTION" name="initializeState" role="operation"
    targetObjectType="objectReference" type="void" proxyInvokeType="multicall">
    <signature>
      <parameter description="The name of the MBean."
        name="mbeanName" type="java.lang.String"/>
      <parameter description="The initial state of the MBean."
        name="mbeanName" type="java.lang.String"/>
    </signature>
  </operation>
  
  <notification name="j2ee.state.starting" severity="6" log="false"
                description="This sample state MBean is in starting state.">
      <notificationType>j2ee.state.starting</notificationType>
  </notification>
  <notification name="j2ee.state.running" severity="6" log="false"
                description="This sample state MBean is in running state.">
      <notificationType>j2ee.state.running</notificationType>
  </notification>
  <notification name="j2ee.state.stopping" severity="6" log="false"
                description="This sample state MBean is in stopping state.">
      <notificationType>j2ee.state.stopping</notificationType>
  </notification>
  <notification name="j2ee.state.stopped" severity="6" log="false"
                description="This sample state MBean is in stopped state.">
      <notificationType>j2ee.state.stopped</notificationType>
  </notification>
</MBean>

SampleState 實作

package com.ibm.ws390.sample;

import com.ibm.ejs.ras.Tr;
import com.ibm.ejs.ras.TraceComponent;
import java.io.Serializable;
import com.ibm.websphere.management.dynamicproxy.StateObject;

public class SampleState extends StateObject {
    
    private static TraceComponent tc =
    Tr.register(SampleState.class,"SampleState",null);
    
    // 受套件保護的 STATE 常數。
    static final String STATE_STARTING = "j2ee.state.starting";
    static final String STATE_RUNNING  = "j2ee.state.running";
    static final String STATE_STOPPING = "j2ee.state.stopping";
    static final String STATE_STOPPED  = "j2ee.state.stopped";
    
    // Dynamicproxy State 是以 STOPPED 狀態來起始設定。
    private String state = STATE_STOPPED;
    
    public SampleState() {
        if (tc.isEntryEnabled()) Tr.entry(tc,"<init>");
        
        // 在 "state" 起始設定期間,會將 State 起始設定,        // 但也可以在這裡,在建構子中起始設定。
        /*
        state = "WebSphere Application Server for z/OS ready for e-business";
        */
        
        if (tc.isEntryEnabled()) Tr.exit(tc,"<init>");
    }
    
    public synchronized String getState() {
        if (tc.isEntryEnabled()) Tr.entry(tc,"getState");
        if (tc.isEntryEnabled()) Tr.exit(tc,"getState",state);
        return state;
    }
    
    public synchronized void setState(String state) {
        if (tc.isEntryEnabled()) Tr.entry(tc,"setState",state);
        this.state = state;
        if (tc.isEntryEnabled()) Tr.exit(tc,"setState");
    }
    
    public synchronized String getStateObjectInfo() {
        return state;
    }
}

SampleStateAggregationHandler 實作

package com.ibm.ws390.sample;

import com.ibm.websphere.management.dynamicproxy.AggregationHandler;
import com.ibm.websphere.management.dynamicproxy.StateObject;

import com.ibm.ejs.ras.Tr;
import com.ibm.ejs.ras.TraceComponent;

public class SampleStateAggregationHandler implements AggregationHandler {
    
    private static TraceComponent tc =
    Tr.register(SampleStateAggregationHandler.class,"SampleState",null);
    
    /**
     * 從多重呼叫的 MBean 作業傳回聚集結果,這個作業
     * 會在所有服務者 MBean 的各結果中進行編譯,且會
     * 針對呼叫的方法,各傳回單一的回覆值。
     *
     * @param  methodName           MBean 方法名稱
     * @param  params               MBean 方法參數
     * @param  signatures           MBean 方法簽章
     * @param  servantMBeanResults  dynamicproxy 多重播送呼叫
     *                              所呼叫的各個服務者 MBean
     *                              實例的結果。
     *                              附註:這個值可以是 "null",也可以是
     *                              "null" 陣列(如果方法的回覆值
     *                              是 "void" 的話)。這個方法的實作
     *                              必須處理這個情況,以
     *                              避免 <code>NullPointerException</code>.
     * @param stateObject
     *        MBean 提供者已提供 <code>StateObject</code>,供
     *        CR 中的 dynamicproxy MBean 用來管理它的狀態。附註:這個物件
     *        有可能是空值,如果未指定 "stateObjectClass" 或在這個
     *         dynamicproxy MBean 的起始設定期間發生內部錯誤。
     *        實作必須適當處理 "null" 輸入。
     *                
     * @return MBean XML 定義給指定的 MBean 作業
     *         的聚集結果。
     */
    public Object aggregateResults(String methodName,
                                   Object[] params,
                                   String[] signatures,
                                   Object[] servantMBeanResults,
                                   StateObject stateObject) {
                                       
        if (tc.isEntryEnabled()) Tr.entry(tc,"aggregateResults",methodName);
        
        // 如您從 SampleStateMBean 的 MBeanDescriptor 中所能見到,        // 它宣告下列四個方法:
        // 1. String getMBeanName()         [proxyInvokeType == unicall]
        // 2. String getState()             [proxyInvokeType == multicall]
        // 3. void setState(String)         [proxyInvokeType == multicall]
        // 4. void initializeState()        [proxyInvokeType == multicall]
        //
        // 從這些方法中,唯一需要聚集的方法
        // 是 #2 getState 方法,它是一個多重呼叫的 MBean 作業,且
        // 會傳回一個可聚集的值。
        //
        // 在這個範例中,我們只是取出每個服務者的 getState MBean
        // 要求結果,將它們連結成一個長字串來
        // 顯示每個服務者的狀態。
        if (methodName.equals("getState")) {
            StringBuffer stateBuf = new StringBuffer();
            
            for (int i=0; i<servantMBeanResults.length; i++) {
                stateBuf.append("SERVANT #" + i + " state ==|" +
                                servantMBeanResults[i] + "|== ");
            }
            return stateBuf.toString();
        }
        // 如果我們也有一個會傳回例如 int 的範例方法
        // getNumberOfMBeans(),它可以採用類似的方式
        // 並在這裡一併新增各服務者的 getNumberOfMBeans() 結果。
        /* 為了不存在的方法而新增的範例:int getNumberOfMBeans()
        else if (methodName.equals("getNumberOfMBeans")) {
            int aggregatedResult = 0;
            
            for (int i=0; i<servantMBeanResults.length; i++) {
                aggregatedResult += (int) servantMBeanResults[i];
            }
            return aggregatedResult;
        }
        */
        
        return methodName + " is NOT handled by " + getClass().getName() + "!";
    }
    
}

指出主題類型的圖示 作業主題



時間戳記圖示 前次更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tjmx_extend
檔名:tjmx_extend.html