標籤: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進行互動的。
分別介紹一下比較重要的一些概念:
通常是一個 Java 類,它提供介面可以使這個類具有可以被管理(能夠成功註冊到server上)的功能。它通常代表我們想要實際管理的一個程式,或者一個裝置等等,這是我們用MBean的規範將管理對象封裝了起來。
是管理MBean的一個 Java 類,你需要向 MBeanServer 註冊一個 MBean 後,這個 MBean 才會真正具備被管理的能力,MBeanServer 還提供了查詢功能和註冊監聽器的功能,sun 提供的只是介面,不同的 JMX 實現中的 MBean server 實現也不同。
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的使用方法
- 定義MBean介面
- 編寫MBean介面實作類別
- 建立MBeanServer類,並向server註冊MBean類(server.registerMBean(實作類別對象,ObjectName)) 【ObjectName取名是有規範的,格式為:“網域名稱:name=MBean名稱”,其中網域名稱和MBean的名稱可以任意取。這樣定義後,就可以唯一標識我們定義的這個MBean的實作類別了。】
- 為了查看實現狀態,可以再加一個Thread.sleep(Long.MAX_VALUE),然後用JConsole工具查看。
JMX服務的訪問方式
JMX服務可以有多種方式對其進行串連和使用,也有不同的展現方式,但內容都是相同的。
1.JDK內建工具JConsole(jdk/bin/jconsole.exe)
- 串連成功後,可以看到如檔案目錄形式展現的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)學習