開發管理用戶端程式

您可以開發管理用戶端程式來使用 WebSphere® Application Server 管理應用程式設計介面 (API) 和「Java™ 管理延伸 (JMX)」。

關於這項作業

產品管理 API 可供控制分散式系統的作業方面,且提供更新配置的能力。 如需 AdminClient 介面的相關資訊,請檢視應用程式設計介面文件。

請參閱 MBean 作業的範例。 如需 MBean 程式設計的相關資訊,請參閱 MBean Java API 文件。在這個資訊中心,按一下參照 > 程式設計介面 > MBean > Mbean 介面

程序

  1. 建立 AdminClient 實例。

    在基本安裝中,管理用戶端程式需要在執行於部署管理程式或應用程式伺服器的 AdminService 物件上呼叫方法。

    AdminClient 類別透過支援的其中一個「Java 管理延伸 (JMX)」連接器,向遠端 AdminService 物件提供 Proxy。
    • 下列範例顯示如何建立「簡易物件存取通訊協定 (SOAP)」連接器的 AdminClient 實例:
      Properties connectProps = new Properties();
      connectProps.setProperty(
      AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);
      
      connectProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
      connectProps.setProperty(AdminClient.CONNECTOR_PORT, "8879");
      connectProps.setProperty(AdminClient.USERNAME, "test2");
      connectProps.setProperty(AdminClient.PASSWORD, "user24test");
      AdminClient adminClient = null;
      try
      {
             adminClient = AdminClientFactory.createAdminClient(connectProps);
      }
      catch (ConnectorException e)
      {
             System.out.println("Exception creating admin client: " + e);
      }
      1. 設定 Properties 物件。

        範例利用訪問伺服器所需的內容來設定 Properties 物件。 在這個情況下,您利用 SOAP 連接器來連接伺服器;對於連接器類型,請使用下列值:AdminClient.CONNECTOR_TYPE_SOAP。

      2. [AIX Solaris HP-UX Linux Windows][IBM i]為了簡便,在伺服器所在的相同機器上執行用戶端程式;使用 localhost 作為主機名稱。

        如果要存取遠端主機而不是本端主機,這個主機要使用可解析的網路名稱。

      3. 設定伺服器 SOAP 連接器用來接聽的埠號。

        在單一伺服器安裝中,應用程式伺服器 SOAP 連接器的預設埠號是 8880。 WebSphere Application Server, Network Deployment 安裝中,部署管理程式 SOAP 連接器的預設埠號是 8879。

      4. 設定連線內容之後,請利用 AdminClientFactory 類別和 Properties 物件來建立連接至所選伺服器的 AdminClient 物件。

        依各種因素(如您所需的通訊協定和安全環境)而定,您可能需要設定其他內容。 比方說,如果您啟用應用程式用戶端程式的安全,就包含 javax.net.ssl.* 內容。 如需 AdminClient 介面、javax.net.ssl.* 內容及和其他建立範例的詳細資訊,請參閱應用程式設計介面文件中的 AdminClient 介面。

    • 下列範例顯示如何建立「遠端方法呼叫 (RMI)」連接器的 AdminClient 實例。 為了列印方便,部分指令分成多行。
      Properties connectProps = new Properties();
      connectProps.setProperty(AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_RMI);
      connectProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
      connectProps.setProperty(AdminClient.CONNECTOR_PORT, "2809");
      connectProps.setProperty(AdminClient.USERNAME, "test2");
      connectProps.setProperty(AdminClient.PASSWORD, "user24test");
      System.setProperty("com.ibm.CORBA.ConfigURL",
       "file:C:/AA/cf010839.26/profiles/AppSrv02/properties/sas.client.props");
      System.setProperty("com.ibm.SSL.ConfigURL",
       "file:C:/AA/cf010839.26/profiles/AppSrv02/properties/ssl.client.props");
      AdminClient adminClient = null;
      try
      {
             adminClient = AdminClientFactory.createAdminClient(connectProps);
      }
      catch (ConnectorException e)
      {
             System.out.println("Exception creating admin client: " + e);
      }
      支援的配置 支援的配置: 在執行於應用程式伺服器的應用程式碼(例如,Servlet 和 JavaServer Pages (JSP) 檔)內使用 createAdminClient 方法時,您必須將 CACHE_DISABLED 內容設為 true。 例如:
      connectProps.setProperty(AdminClient.CACHE_DISABLED, "true");
      sptcfg
      1. 設定 Properties 物件。

        範例利用訪問伺服器所需的內容來設定 Properties 物件。 在這個情況下,您利用「遠端方法呼叫」連接器來連接伺服器;對於連接器類型,請使用下列值:AdminClient.CONNECTOR_TYPE_RMI。

      2. [AIX Solaris HP-UX Linux Windows][IBM i]為了簡便,在伺服器所在的相同機器上執行用戶端程式;使用 localhost 作為主機名稱。

        如果要存取遠端主機而不是本端主機,這個主機要使用可解析的網路名稱。

      3. 設定伺服器 RMI 連接器用來接聽的埠號。

        在單一伺服器安裝中,應用程式伺服器 RMI 連接器的預設埠號是 2809。 在 WebSphere Application Server, Network Deployment 安裝中,部署管理程式 RMI 連接器的預設埠號是 9809。

      4. 設定連線內容之後,請利用 AdminClientFactory 類別和 Properties 物件來建立連接至所選伺服器的 AdminClient 物件。

        依各種因素(如您所需的通訊協定和安全環境)而定,您可能需要設定其他內容。 比方說,如果您啟用應用程式用戶端程式的安全,您必須設定一個系統內容來指向 ssl.client.props 檔和 sas.client.props 檔。 如果在本端機器上執行,您可以指向實際位置。 如果在遠端機器上執行,您可以從伺服器機器中複製這些內容檔,然後將檔案放在您想要的任何位置,指定您放置它們的路徑。

        您可以在 sas.client.props 檔中指定使用者名稱和密碼,當您這樣做時,請指定 com.ibm.CORBA.loginSource=properties。 如果您想在用戶端程式中設定使用者名稱和密碼,請在 sas.client.props 檔中指定 com.ibm.CORBA.loginSource=none

  2. 尋找一個 MBean。

    當您取得 AdminClient 實例時,您可以利用它來存取管理伺服器和應用程式伺服器中的受管理資源。 每個受管理資源都會向 AdminService 登錄一個 MBean,您可以透過它來存取資源。 這個 MBean 由識別 MBean 的 ObjectName 實例來代表。 ObjectName 實例由網域名稱後面接著一組一或多個未排序的關鍵內容組成。 網域名稱的語法如下:

    [domainName]:property=value[,property=value]*
    對於 WebSphere Application Server,網域名稱是 WebSphere,針對管理而定義的關鍵內容如下:
    表 1. 關鍵內容說明. 關鍵內容包含 types、name、cell、node 和 process。
    關鍵內容 說明
    type MBean 的類型。例如:Server、TraceService、Java 虛擬機器 (JVM)。
    name MBean 個別實例的名稱 ID。
    cell MBean 執行所在的 Cell 名稱。
    node MBean 執行所在的節點名稱。
    process MBean 執行所在的程序名稱。

    WebSphere Application Server 中的某些 MBean 會使用其他關鍵內容。 在 WebSphere Application Server 程序中,您可以向 MBean 伺服器登錄沒有關鍵內容的 MBean。 不過,這類 MBean 不能參與產品新增的分散式加強功能,例如,要求路由、分散式事件通知等等。

    如果您知道 ObjectName 實例的全套關鍵內容,您可以利用它來尋找它識別的 MBean。 不過,在不需知道所有關鍵內容的情況下尋找 MBean,通常會比較實際,也比較便利。 請利用萬用字元星號 (*) 來代表不需要符合的任何關鍵內容。 下表提供一些有萬用字元關鍵內容符合單一或多個 MBean 的物件名稱範例。
    表 2. 含有萬用字元關鍵內容的物件名稱範例. 包含星號 (*) 來指定萬用字元關鍵內容。
    物件名稱 說明
    *:type=Server,* 類型為伺服器的所有 MBean
    *:node=Node1,type=Server,* Node1 上類型為伺服器的所有 MBean
    *:type=JVM,process=server1,node=Node1,* Node1 節點上名稱為 server1 的伺服器其中的 JVM MBean
    *:process=server1,* 名稱為 server1 的所有伺服器其中的所有 MBean
    *:process=server1,node=Node1,* Node1 上名稱為 server1 的伺服器其中的所有 MBean

    您可以利用符合關鍵內容的物件名稱查詢 MBean 來尋找它。 下列範例顯示如何尋找 MyNode 節點之節點代理程式的 MBean:

    String nodeName = "MyNode";
    String query = "WebSphere:type=NodeAgent,node=" + nodeName + ",*";
    ObjectName queryName = new ObjectName(query);
    ObjectName nodeAgent = null;
    Set s = adminClient.queryNames(queryName, null);
    if (!s.isEmpty())
        nodeAgent = (ObjectName)s.iterator().next();
    else
        System.out.println("Node agent MBean was not found");
    1. 利用指定關鍵內容 type 和 node 的查詢字串來建置 ObjectName 實例。

      這個型樣利用萬用字元來代表其餘關鍵內容,以符合 MyNode 節點上類型為 NodeAgent 之所有 MBean 的物件名稱。 由於每個節點只存在一個節點代理程式,所以這項資訊足以識別您想要的 MBean。

    2. 將這個 ObjectName 實例提供給 AdminClient 介面的 queryNames 方法。

      AdminClient 介面會執行對 AdminService 介面的遠端呼叫,以取得一組符合查詢的 MBean 物件名稱。 這個方法的第二個空參數是一個查詢表示式 (QueryExp) 物件,可用來作為另一項查詢,以涵蓋符合第一個參數中 ObjectName 型樣的 MBean。

    3. 利用設定反覆運算子來取得第一個(在這個情況下也是唯一的)元素。

      這個元素是節點代理程式的 MBean ObjectName 實例。

  3. 使用 MBean。

    特定 MBean 可以執行的作業,取決於這個 MBean 的管理介面。 MBean 可以宣告:

    • 您可以取得或設定的屬性
    • 您可以呼叫的作業
    • 您可以登錄其接聽器的通知
    對於 WebSphere Application Server 提供的 MBean,您可以在 MBean API 文件中找到它們支援之介面的相關資訊。 下列範例在先前找到的節點代理程式 MBean 上,呼叫其中一個可用的作業。 下列範例會啟動 MyServer 應用程式伺服器:
    String opName = "launchProcess";
    String signature[] = { "java.lang.String" };
    String params[] = { "MyServer" };
    try
    {
         adminClient.invoke(nodeAgent, opName, params, signature);
    }
    catch (Exception e)
    {
         System.out.println("Exception invoking launchProcess: " + e);
    }
    AdminClient.invoke 方法是用來在任何 MBean 上呼任何作業的通用方法。 參數如下:
    • 目標 MBean 的物件名稱 nodeAgent
    • 作業的名稱 opName
    • 包含作業參數的物件陣列 params
    • 包含作業簽章的字串陣列 signature
    範例中的 launchProcess 作業有單一參數,它是用來識別要啟動的伺服器的字串。

    呼叫方法會傳回一個物件實例,呼叫端程式碼可以利用它來強制轉型為所呼叫作業的正確傳回類型。 launchProcess 作業宣告為 void,因此,在這個範例中,您可以忽略回覆值。

  4. 登錄事件。

    除了管理資源之外,JMX API 也支援特定管理事件的應用程式監視。 某些事件會產生通知,例如,當伺服器啟動時。 管理應用程式可以登錄為這些通知的接聽器。 WebSphere Application Server 提供了 JMX 通知模型的完整實作,也提供了其他功能,以便您在分散式環境中接收通知。 如需從產品 MBean 發出之通知的完整清單,請參閱 MBean API 文件中的 com.ibm.websphere.management.NotificationConstants 類別。

    下列範例顯示物件如何利用 ObjectName 節點代理程式來登錄從 MBean 發出的事件通知:

    adminClient.addNotificationListener(nodeAgent, this, null, null);

    在這個範例中,第一個參數是節點代理程式 MBean 的 ObjectName。 第二個參數用來識別必須實作 NotificationListener 介面的接聽器物件。 在這個情況下,呼叫端物件是接聽器。 第三個參數是一個過濾器,供您用來指示要接收的通知。 將這個值保留為 null 時,您會收到這個 MBean 的所有通知。 最後一個參數是一個 handback 物件,供您用來將 JMX API 設為在發出通知時傳回給您。

    如果您的 MBean 位於 Cell 中的另一個伺服器,即使管理用戶端程式有可能連接至部署管理程式伺服器,您也可以收到它的通知。 所有通知都會傳到上游伺服器。 例如,來自應用程式伺服器的通知首先會傳到本端節點代理程式,然後到部署管理程式。

    Application Server 提供的另一個加強特性是,能夠用單一呼叫來登錄為多個 MBean 的通知接聽器。 這個登錄是透過 AdminClient 介面的 addNotificationListenerExtended 方法來完成,是標準 JMX addNotificationListener 方法的延伸。 這個延伸方法甚至可讓您登錄目前不在作用中的 MBean。 當您想要監視其事件的資源有可能在您的管理用戶端程式的生命期限內停止並重新啟動時,這個登錄便很重要。

  5. 處理事件。

    物件透過 handleNotification 方法來接收 JMX 事件通知,NotificationListener 介面定義了這個方法,任何事件接收端都必須實作它。 下列範例是 handleNotification 方法的實作,它會報告收到的通知:

    public void handleNotification(Notification n, Object handback)
    {
         System.out.println("***************************************************");
         System.out.println("* Notification received at " + new Date().toString());
         System.out.println("* type      = " + ntfyObj.getType());
         System.out.println("* message   = " + ntfyObj.getMessage());
         System.out.println("* source    = " + ntfyObj.getSource());
         System.out.println(
         "* seqNum    = " + Long.toString(ntfyObj.getSequenceNumber()));
         System.out.println("* timeStamp = " + new Date(ntfyObj.getTimeStamp()));
         System.out.println("* userData  = " + ntfyObj.getUserData());
         System.out.println("***************************************************");
    }

結果

管理用戶端可以處理從 MBean 發出的事件通知。

避免困難 避免困難: 如果用戶端程式透過 RMI 或 JSR160RMI 連接器來登錄通知接聽器,且 ORB 執行緒未停止執行,並因此阻止 Java 虛擬機器結束,請將 System.exit() 陳述式新增到用戶端程式中。 ORB 會啟動一個執行緒來處理對用戶端的通知傳播。 這個執行緒不會隨著用戶端主要執行緒而自動結束,除非主要執行緒有 System.exit() 陳述式。 請將 System.exit() 陳述式放在用戶端程式中,允許 ORB 執行緒和主要執行緒停止處理的位置。 例如,將 System.exit() 陳述式放在用戶端程式主要 try 區塊的 catchfinally 子句中。gotcha

範例:管理用戶端程式

請將內容複製到名稱為 AdminClientExample.java 的檔案中。 將節點名稱和伺服器名稱變更為您的配置所適用的值之後,您可以依照利用 WebSphere Application Server 管理 Java API 來建立自訂 Java 管理用戶端程式中的指示來編譯及執行它。
import java.util.Date;
import java.util.Properties;
import java.util.Set;

import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;

import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.AdminClientFactory;
import com.ibm.websphere.management.exception.ConnectorException;

public class AdminClientExample implements NotificationListener
{

    private AdminClient adminClient;
    private ObjectName nodeAgent;
    private long ntfyCount = 0;

    public static void main(String[] args) {
       AdminClientExample ace = new AdminClientExample();

       // Create an AdminClient
       ace.createAdminClient();

       // Find a NodeAgent MBean
       ace.getNodeAgentMBean("ellington");

       // Invoke launchProcess
       ace.invokeLaunchProcess("server1");

       // Register for NodeAgent events
       ace.registerNotificationListener();
        
       // Run until interrupted
       ace.countNotifications();
    }

    private void createAdminClient()
    {
        // Set up a Properties object for the JMX connector attributes
        Properties connectProps = new Properties();
        connectProps.setProperty(
        AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);
        connectProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
        connectProps.setProperty(AdminClient.CONNECTOR_PORT, "8879");
        
        // Get an AdminClient based on the connector properties
        try
        {
            adminClient = AdminClientFactory.createAdminClient(connectProps);
        }
        catch (ConnectorException e)
        {
            System.out.println("Exception creating admin client: " + e);
            System.exit(-1);
        }
        
        System.out.println("Connected to DeploymentManager");
    }
    
    
    private void getNodeAgentMBean(String nodeName)
    {
        // Query for the ObjectName of the NodeAgent MBean on the given node
        try
        {
            String query = "WebSphere:type=NodeAgent,node=" + nodeName + ",*";
            ObjectName queryName = new ObjectName(query);
            Set s = adminClient.queryNames(queryName, null);
            if (!s.isEmpty())
                nodeAgent = (ObjectName)s.iterator().next();
            else
            {
                System.out.println("Node agent MBean was not found");
                System.exit(-1);
            }
        }
        catch (MalformedObjectNameException e)
        {
            System.out.println(e);
            System.exit(-1);
        }
        catch (ConnectorException e)
        {
            System.out.println(e);
            System.exit(-1);
        }
        
        System.out.println("Found NodeAgent MBean for node " + nodeName);
    }
    
    private void invokeLaunchProcess(String serverName)
    {
        // Use the launchProcess operation on the NodeAgent MBean to start
        // the given server
        String opName = "launchProcess";
        String signature[] = { "java.lang.String" };
        String params[] = { serverName };
        boolean launched = false;
        try
        {
            Boolean b = (Boolean)adminClient.invoke(
            
nodeAgent, opName, params, signature);
            launched = b.booleanValue();
            if (launched)
                System.out.println(serverName + " was launched");
            else
                System.out.println(serverName + " was not launched");

        }
        catch (Exception e)
        {
            System.out.println("Exception invoking launchProcess: " + e);
        }
    }
    
    private void registerNotificationListener()
    {
        // Register this object as a listener for notifications from the
        // NodeAgent MBean.  Don't use a filter and don't use a handback
        // object.
        try
        {
            adminClient.addNotificationListener(nodeAgent, this, null, null);
            System.out.println("Registered for event notifications");
        }
        catch (InstanceNotFoundException e)
        {
            System.out.println(e);
            e.printStackTrace();
        }
        catch (ConnectorException e)
        {
            System.out.println(e);
            e.printStackTrace();
        }
    }
    
    public void handleNotification(Notification ntfyObj, Object handback)
    {
        // Each notification that the NodeAgent MBean generates will result in
        // this method being called
        ntfyCount++;
        System.out.println("***************************************************");
        System.out.println("* Notification received at " + new Date().toString());
        System.out.println("* type      = " + ntfyObj.getType());
        System.out.println("* message   = " + ntfyObj.getMessage());
        System.out.println("* source    = " + ntfyObj.getSource());
        System.out.println(
        "* seqNum    = " + Long.toString(ntfyObj.getSequenceNumber()));
        System.out.println("* timeStamp = " + new Date(ntfyObj.getTimeStamp()));
        System.out.println("* userData  = " + ntfyObj.getUserData());
        System.out.println("***************************************************");

    }
    
    private void countNotifications()
    {
        // Run until killed
        try
        {
            while (true)
            {
                Thread.currentThread().sleep(60000);
                System.out.println(ntfyCount + " notification have been received");
            }
        }
        catch (InterruptedException e)
        {
        }
    }
    
}

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



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