JMX(Java Management Extension)學習

來源:互聯網
上載者:User

標籤:elm   網站   展現   change   connect   sys   pen   ever   orm   

目錄

  • 基本概念
  • MBean的種類
    • StandardMBean
    • DynamicBean
    • ModelMBean
  • JMX的實現方式
  • StandardMBean的使用方法
  • JMX服務的訪問方式
  • JMX——Notifications
基本概念

JMX(Java Management Extensions)是一個為應用程式植入管理功能的架構。

JMX讓程式有被管理的功能,例如你開發一個WEB網站,它是在24小時不間斷運行,那麼你肯定會對網站進行監控,如每天的UV、PV是多少;又或者在業務高峰的期間,你想對介面進行限流,就必須去修改介面並發的配置值。

JMX架構主要由以下幾層構成:

  • 探針層(Probe Level)/裝置層(Instrumentation Level)
  • 代理層(Agent Level)
  • 遠端管理層(Remote Management Level)

它們之間的關係如所示:

需要通過JMX服務獲得被管理對象資訊的程式,就是通過遠端管理層來與具體的MBean進行互動的。

分別介紹一下比較重要的一些概念:

  • MBean(Managed Bean)

通常是一個 Java 類,它提供介面可以使這個類具有可以被管理(能夠成功註冊到server上)的功能。它通常代表我們想要實際管理的一個程式,或者一個裝置等等,這是我們用MBean的規範將管理對象封裝了起來。

  • MBeanServer

是管理MBean的一個 Java 類,你需要向 MBeanServer 註冊一個 MBean 後,這個 MBean 才會真正具備被管理的能力,MBeanServer 還提供了查詢功能和註冊監聽器的功能,sun 提供的只是介面,不同的 JMX 實現中的 MBean server 實現也不同。

  • JMX Agent

Agent 是 MBean Server 的容器,主要為了管理一系列的 MBean,並且提供的一系列的服務,通常有MBean relationships, dynamically loading classes, simple monitoring services, timers。Agent 可以利用 Protocol adapters(例如 HTTP 和 SNMP)和 connectors(RMI 和Jini)使不同的用戶端可以訪問 MBean。

  • Protocol adapters 和 connectors

適配器和連接器主要使不同的協議和用戶端可以使用這個 Agent,一個 Agent 中可以有多個 Protocol adapters 和 connectors,這樣管理起 MBean 來就更方便了(有多種類型的用戶端和協議可以操作 MBean)。注意,Protocol adapters 和 connectors 通常也是 MBean。

【JMX學習】1、jmx入門

JMX超詳細解讀

MBean的種類
  • standard MBean:需要定義MBean介面,介面中包含需要被管理的資源,並編寫MBean介面的實作類別。介面和實作類別的命名必須滿足一定規範,若實作類別名為Classname,則介面的命名必須為ClassNameMBean。
  • dynamic MBean:必須實現javax.management.DynamicMBean介面,所有的屬性,方法都在運行時定義。
  • open MBean:此MBean的規範還不完善,正在改進中
  • model MBean:與標準和動態MBean相比,你可以不用寫MBean類,只需使用javax.management.modelmbean.RequiredModelMBean即可。RequiredModelMBean實現了ModelMBean介面,而ModelMBean擴充了DynamicMBean介面,因此與DynamicMBean相似,Model MBean的管理資源也是在運行時定義的。與DynamicMBean不同的是,DynamicMBean管理的資源一般定義在DynamicMBean中(運行時才決定管理那些資源),而model MBean管理的資源並不在MBean中,而是在外部(通常是一個類),只有在運行時,才通過set方法將其加入到model MBean中。

JMX學習筆記(一)-MBean

StandardMBean

從零開始玩轉JMX(一)——簡介和Standard MBean

JMX學習筆記(三):MXBean

MXBean相比MBean支援更複雜資料類型的類屬性管理

DynamicBean

動態MBean:DynamicMBean

ModelMBean

從零開始玩轉JMX(三)——Model MBean

JMX的實現方式StandardMBean的使用方法
  1. 定義MBean介面
  2. 編寫MBean介面實作類別
  3. 建立MBeanServer類,並向server註冊MBean類(server.registerMBean(實作類別對象,ObjectName)) 【ObjectName取名是有規範的,格式為:“網域名稱:name=MBean名稱”,其中網域名稱和MBean的名稱可以任意取。這樣定義後,就可以唯一標識我們定義的這個MBean的實作類別了。】
  4. 為了查看實現狀態,可以再加一個Thread.sleep(Long.MAX_VALUE),然後用JConsole工具查看。
JMX服務的訪問方式

JMX服務可以有多種方式對其進行串連和使用,也有不同的展現方式,但內容都是相同的。

1.JDK內建工具JConsole(jdk/bin/jconsole.exe)

  • 首先串連JMX服務。

    JMX服務或者是本地提供,或者是遠程提供,本地提供可以直接在jconsole的串連介面上顯示,選中串連即可。遠程提供的串連,則需要輸入遠程地址和連接埠號碼,並且如果設定了帳號密碼還需要輸入帳號密碼,然後串連。

  • 串連成功後,可以看到如檔案目錄形式展現的MBean,可以點擊展開,查看屬性,或者即時調用方法(在MBean介面實作類別中實現的非屬性相關的get/set方法都可以調用)。

2.通過JMX提供的工具頁訪問

這裡需要到匯入外部jar包jdmk

package jmx;import java.lang.management.ManagementFactory;import javax.management.JMException;import javax.management.MBeanServer;import javax.management.ObjectName;import com.sun.jdmk.comm.HtmlAdaptorServer;public class HelloAgent{    public static void main(String[] args) throws JMException, Exception    {         MBeanServer server = ManagementFactory.getPlatformMBeanServer();         ObjectName helloName = new ObjectName("jmxBean:name=hello");         //create mbean and register mbean         server.registerMBean(new Hello(), helloName);                  //這裡需要對Html適配器的MBean進行註冊,並啟動適配器,這樣就可以通過網頁來使用JMX。         ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");            HtmlAdaptorServer adapter = new HtmlAdaptorServer();            server.registerMBean(adapter, adapterName);           adapter.start();    }}

訪問地址:http://localhost:8082,點擊name=hello:

3.通過用戶端程式進行遠端存取(RMI)

當然,需要先啟動JMX服務,並監聽連接埠才可以訪問。

package jmx;import java.io.IOException;import javax.management.Attribute;import javax.management.MBeanServerConnection;import javax.management.MBeanServerInvocationHandler;import javax.management.ObjectName;import javax.management.remote.JMXConnector;import javax.management.remote.JMXConnectorFactory;import javax.management.remote.JMXServiceURL;public class Client{    public static void main(String[] args) throws IOException, Exception, NullPointerException    {        /**         * JMX提供服務的url         * @type {JMXServiceURL}         */        JMXServiceURL url = new JMXServiceURL            ("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");                /**         * JMX服務連接器,用於發起串連         * @type {[type]}         */        JMXConnector jmxc = JMXConnectorFactory.connect(url,null);                /**         * 從JMX服務連接器上擷取的MBeanServer連接器。         * @type {[type]}         */        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();        //ObjectName的名稱與前面註冊時候的保持一致        ObjectName mbeanName = new ObjectName("jmxBean:name=hello");                System.out.println("Domains ......");                //獲得所有server下的網域名稱        String[] domains = mbsc.getDomains();                for(int i=0;i<domains.length;i++)        {            System.out.println("domain[" + i + "]=" + domains[i] );        }                //獲得所有註冊在該server上的MBean數目        System.out.println("MBean count = " + mbsc.getMBeanCount());        //設定指定Mbean的特定屬性值        //這裡的setAttribute、getAttribute操作只能針對bean的屬性        //例如對getName或者setName進行操作,只能使用Name,需要去除方法的首碼        mbsc.setAttribute(mbeanName, new Attribute("Name","杭州"));        mbsc.setAttribute(mbeanName, new Attribute("Age","1990"));        String age = (String)mbsc.getAttribute(mbeanName, "Age");        String name = (String)mbsc.getAttribute(mbeanName, "Name");        System.out.println("age=" + age + ";name=" + name);                        /**         * 通過JMX調用MBean執行個體的方法         */                //方法一        //通過獲得代理調用MBean執行個體的方法        HelloMBean proxy = MBeanServerInvocationHandler.            newProxyInstance(mbsc, mbeanName, HelloMBean.class, false);        proxy.helloWorld();        proxy.helloWorld("migu");        proxy.getTelephone();                //方法二        //通過msbc的invoke方法調用MBean執行個體的方法,只針對非屬性的相關的方法(get/set)        //例如invoke不能對getName方法進行調用        mbsc.invoke(mbeanName, "getTelephone", null, null);        mbsc.invoke(mbeanName, "helloWorld",             new String[]{"I‘ll connect to JMX Server via client2"}, new String[]{"java.lang.String"});        mbsc.invoke(mbeanName, "helloWorld", null, null);    }}
JMX——Notifications

從零開始玩轉JMX(二)——Condition

JMX學習筆記(四):Notifications

JMX API定義了一種機制,使MBean能組建通知,如當訊號狀態改變,檢測到事件或者一個問題時。

通知模型僅僅涉及了在同一個JMX代理中的管理構件之間的事件傳播。JMX通知模型依靠以下幾個部分:

  • Notification,一個通用的事件類型,該類標識事件的類型,可以被直接使用,也可以根據傳遞的事件的需要而被擴充。
  • NotificationListener介面,接受通知的對象需實現此介面。
  • NotificationFilter介面,作為通知過濾器的對象需實現此介面,為通知監聽者提供了一個過濾通知的過濾器。
  • NotificationBroadcaster介面,通知寄件者需實現此介面,該介面允許希望得到通知的監聽者註冊。

發送一個通用類型的通知,任何一個監聽者都會得到該通知。因此,監聽者需提供過濾器來選擇所需要接受的通知。任何類型的MBean,標準的或動態,都可以作為一個通知寄件者,也可以作為一個通知監聽者,或兩者都是。

要組建通知,MBean必須實現NotificationEmitter介面或繼承NotificationBroadcasterSupport類。要發送一個通知必須構造Notification類的執行個體或者子類(如NotificationChangedAttribute),通知執行個體產生後,由NotificationBroadcasterSupport的sendNotification方法發送通知。

  • 例子:

Step 1 :定義HelloMBean介面

    package com.jmx.demo5;            public interface HelloMBean {          public void sayHello();                public int add(int x, int y);                public String getName();                public int getCacheSize();                public void setCacheSize(int size);            }  

Step 2 :編寫HelloMBean的實作類別Hello

    package com.jmx.demo5;            import javax.management.AttributeChangeNotification;      import javax.management.MBeanNotificationInfo;      import javax.management.Notification;      import javax.management.NotificationBroadcasterSupport;            //MBean must extends NotificationBroadcasterSupport or implements NotificationEmitter      public class Hello extends NotificationBroadcasterSupport implements HelloMBean {          private final String name = "Reginald";          private int cacheSize = DEFAULT_CACHE_SIZE;          private static final int DEFAULT_CACHE_SIZE = 200;          private long sequenceNumber = 1;                public void sayHello() {              System.out.println("hello, world");          }                public int add(int x, int y) {              return x + y;          }                public String getName() {              return this.name;          }                public int getCacheSize() {              return this.cacheSize;          }                public synchronized void setCacheSize(int size) {              int oldSize = this.cacheSize;              this.cacheSize = size;              System.out.println("Cache size now " + this.cacheSize);                    /**              * To send a notification,you need to construct an instance of class              * Notification or a Subclass(such as AttributeChangedNotification),and              * pass the instance to NotificationBroadcastSupport.sendNotification.              *               */              Notification n = new AttributeChangeNotification(this,                      sequenceNumber++, System.currentTimeMillis(),                      "CacheSize changed", "CacheSize", "int", oldSize,                      this.cacheSize);                    sendNotification(n);          }                @Override          public MBeanNotificationInfo[] getNotificationInfo() {              String[] types = new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE };              String name = AttributeChangeNotification.class.getName();              String description = "An attribute of this MBean has changed";              MBeanNotificationInfo info = new MBeanNotificationInfo(types, name,                      description);              return new MBeanNotificationInfo[] { info };          }            }  

Step 3:建立MBeanServer,標識MBean,註冊MBean,並運行Main方法:

    package com.jmx.demo5;            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 mbs = ManagementFactory.getPlatformMBeanServer();              ObjectName name = new ObjectName("com.jmx.demo:type=Hello");              Hello mbean = new Hello();              mbs.registerMBean(mbean, name);              System.out.println("Waiting forever...");              Thread.sleep(Long.MAX_VALUE);                        }      }  

然後可以用jconsole開啟JMX服務,查看運行結果:通知選項初始狀態沒有值,點擊訂閱後,通知項為0

!pic

更改CacheSize的值後,在觀察通知選項,變為1

總結:

Notification可以用於監測任何有關MBean方法調用的資訊,只要MBean實作類別繼承NotificationBroadcasterSupport類,然後在需要監測的方法中調用NotificationBroadcasterSupport處繼承來的sendNotification(Notification n)方法即可,而方法的參數是一個Notification執行個體,需要傳入相關的通知資訊。

JMX(Java Management Extension)學習

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.