JAVA監(jiān)控JMX的使用
1.概述
什么是JMX,首先來看一段對(duì)話:
Java Management Extensions(JMX)是一種Java標(biāo)準(zhǔn),用于管理和監(jiān)控Java應(yīng)用程序,特別是分布式系統(tǒng)。它提供了一種標(biāo)準(zhǔn)化的方式來管理應(yīng)用程序的各種方面,包括性能監(jiān)控、配置更改、事件通知等。目前JMX最常用的就是用來做JAVA程序的監(jiān)控,市面上常見的Java 監(jiān)控框架基本都是基于JMX來實(shí)現(xiàn)的。
JMX分為三部分:
MBean:MBean是用來提供功能的,MBean是管理對(duì)象的標(biāo)準(zhǔn)接口,通過MBean可以獲取和操作應(yīng)用程序的各種屬性和操作。Java提供了幾種類型的MBean,包括標(biāo)準(zhǔn)MBean、動(dòng)態(tài)MBean、模型MBean等,每種類型適用于不同的場(chǎng)景。
MBean服務(wù)器:MBean服務(wù)器是用來管理MBean的,它是一個(gè)注冊(cè)表,用于注冊(cè)和管理MBean。應(yīng)用程序通過MBean服務(wù)器暴露MBean,并且其他應(yīng)用程序或工具可以連接到MBean服務(wù)器以檢索和操作這些MBean。
JMX代理:JMX代理是用來訪問MBean服務(wù)器的,可以理解為CS架構(gòu)中的client端,支持多種訪問方式。JMX代理是一個(gè)位于應(yīng)用程序和MBean服務(wù)器之間的中間層,用于管理遠(yuǎn)程應(yīng)用程序。它允許遠(yuǎn)程管理工具連接到遠(yuǎn)程應(yīng)用程序的MBean服務(wù)器,并執(zhí)行各種管理操作,如監(jiān)控、配置和診斷。
JMX標(biāo)準(zhǔn)的實(shí)現(xiàn)通常由Java虛擬機(jī)(JVM)提供支持。Java虛擬機(jī)會(huì)實(shí)現(xiàn)JMX標(biāo)準(zhǔn),以便應(yīng)用程序可以利用JMX的功能。JVM會(huì)提供一個(gè)MBean服務(wù)器,應(yīng)用程序可以將MBean注冊(cè)到該服務(wù)器中,使其可供其他應(yīng)用程序或工具訪問和操作。
Java虛擬機(jī)通過提供標(biāo)準(zhǔn)的MBean服務(wù)器和相關(guān)的API,為應(yīng)用程序提供了一種標(biāo)準(zhǔn)化的方式來管理和監(jiān)控應(yīng)用程序的各個(gè)方面。這種標(biāo)準(zhǔn)化使得開發(fā)人員可以使用相同的接口和工具來管理不同的Java應(yīng)用程序,從而提高了管理的效率和一致性。
2.MBean
MBean服務(wù)器由于是JVM實(shí)現(xiàn)的,所以對(duì)我們應(yīng)用開發(fā)者來說,最核心的其實(shí)就是MBean了,因?yàn)镸Bean是用來實(shí)現(xiàn)功能的。JMX標(biāo)準(zhǔn)中將MBean分為以下幾種:
Standard MBean(標(biāo)準(zhǔn) MBean):它是最簡(jiǎn)單的一種 MBean 類型。一個(gè)標(biāo)準(zhǔn) MBean 由一個(gè) Java 接口和一個(gè)對(duì)應(yīng)的實(shí)現(xiàn)類組成。接口中定義了 MBean 的屬性和操作,實(shí)現(xiàn)類則提供了對(duì)應(yīng)的實(shí)現(xiàn)。標(biāo)準(zhǔn) MBean 的命名約定為
YourInterfaceNameMBean
。Dynamic MBean(動(dòng)態(tài) MBean):與標(biāo)準(zhǔn) MBean 不同,動(dòng)態(tài) MBean 可以在運(yùn)行時(shí)動(dòng)態(tài)地確定其屬性和操作。動(dòng)態(tài) MBean 的屬性和操作是在運(yùn)行時(shí)通過方法調(diào)用來確定的,因此可以根據(jù)需要進(jìn)行動(dòng)態(tài)修改。
Model MBean(模型 MBean):模型 MBean 是一種特殊的 MBean,它通過描述符來描述其管理接口,可以在運(yùn)行時(shí)動(dòng)態(tài)地配置其屬性和操作。模型 MBean 可以通過 XML 或者通過程序動(dòng)態(tài)地加載描述符。
MXBean:MXBean 是一種專門用于 JMX 的 MBean 類型。它定義了一種簡(jiǎn)單的 Java 接口和實(shí)現(xiàn)約定,用于描述 MBean 的屬性和操作,同時(shí)這些接口和實(shí)現(xiàn)類遵循 Java Bean 的命名約定。MXBean 在 JMX 中用于管理特定類型的對(duì)象,例如內(nèi)存使用情況、線程信息等。
Open MBean:開放 MBean 是一種通用的 MBean 類型,它可以包含各種類型的屬性和操作。開放 MBean 不限制其屬性和操作的類型,因此可以包含任意類型的數(shù)據(jù)。
2.1.Standard MBean
所謂的Standard MBean,就是說按照J(rèn)MX的命名規(guī)范來定義接口然后注冊(cè)到MBean Server中,MBean就能被JMX的client端訪問到。具體該MBean提供了什么功能,在這個(gè)自定義的MBean中去定義屬性和方法仔細(xì)實(shí)現(xiàn)即可。
代碼示例:
// 定義一個(gè)接口,命名約定為 YourInterfaceNameMBean public interface HelloMBean { String getName(); void setName(String name); void sayHello(); } ? // 實(shí)現(xiàn)上述接口的類 public class Hello implements HelloMBean { private String name; ? @Override public String getName() { return name; } ? @Override public void setName(String name) { this.name = name; } ? @Override public void sayHello() { System.out.println("Hello, " + name + "!"); } } ? // 主程序 public class Main { public static void main(String[] args) throws Exception { // 創(chuàng)建標(biāo)準(zhǔn) MBean 實(shí)例 HelloMBean helloMBean = new Hello(); // 創(chuàng)建 MBeanServer MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // 創(chuàng)建 ObjectName,用于標(biāo)識(shí) MBean ObjectName name = new ObjectName("com.example:type=Hello"); // 注冊(cè) MBean 到 MBeanServer mbs.registerMBean(helloMBean, name); // 等待一段時(shí)間,使得可以通過 JConsole 或者其他 JMX 客戶端來操作 MBean Thread.sleep(Long.MAX_VALUE); } }
2.2.Dynamic MBean
動(dòng)態(tài) MBean 是 Java Management Extensions (JMX) 中的一種特殊類型的 MBean,它與標(biāo)準(zhǔn) MBean 不同之處在于,動(dòng)態(tài) MBean 允許在運(yùn)行時(shí)動(dòng)態(tài)地確定其屬性和操作,這使得動(dòng)態(tài) MBean 能夠在運(yùn)行時(shí)根據(jù)需要?jiǎng)討B(tài)地調(diào),而不是在編譯時(shí)就確定了。
說人話就是很方便動(dòng)態(tài)的去修改Dynamic MBean的屬性,這非常適合拿來做一些動(dòng)態(tài)的功能,比如:
動(dòng)態(tài)配置管理,從外部去加載配置文件,實(shí)現(xiàn)配置的動(dòng)態(tài)變化。
動(dòng)態(tài)監(jiān)控,從外部去獲取監(jiān)控信息,比如實(shí)時(shí)的CPU、內(nèi)存的信息,實(shí)現(xiàn)對(duì)系統(tǒng)的動(dòng)態(tài)監(jiān)控。
動(dòng)態(tài) MBean 的核心是實(shí)現(xiàn) DynamicMBean
接口,該接口定義了一組方法,用于動(dòng)態(tài)地獲取和設(shè)置 MBean 的屬性,執(zhí)行 MBean 的操作,以及獲取 MBean 的元數(shù)據(jù)信息。以下是 DynamicMBean
接口的幾個(gè)核心方法:
getAttribute(String attribute)
:根據(jù)屬性名獲取屬性值。setAttribute(Attribute attribute)
:設(shè)置指定屬性的值。getAttributes(String[] attributes)
:批量獲取屬性值。setAttributes(AttributeList attributes)
:批量設(shè)置屬性值。invoke(String actionName, Object[] params, String[] signature)
:執(zhí)行指定的操作。getMBeanInfo()
:獲取 MBean 的元數(shù)據(jù)信息,包括屬性、操作和描述信息。
代碼示例:
import javax.management.*; import java.lang.management.ManagementFactory; ? public class DynamicHello implements DynamicMBean { private String name; ? @Override public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { if (attribute.equals("Name")) { return name; } else { throw new AttributeNotFoundException("Attribute '" + attribute + "' not found"); } } ? @Override public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { if (attribute.getName().equals("Name")) { name = (String) attribute.getValue(); } else { throw new AttributeNotFoundException("Attribute '" + attribute.getName() + "' not found"); } } ? @Override public AttributeList getAttributes(String[] attributes) { AttributeList attrs = new AttributeList(); for (String attr : attributes) { try { Object value = getAttribute(attr); attrs.add(new Attribute(attr, value)); } catch (Exception e) { // Ignore if attribute not found } } return attrs; } ? @Override public AttributeList setAttributes(AttributeList attributes) { AttributeList responseAttrs = new AttributeList(); for (Attribute attr : attributes.asList()) { try { setAttribute(attr); responseAttrs.add(new Attribute(attr.getName(), getAttribute(attr.getName()))); } catch (Exception e) { // Ignore if attribute not found or set failed } } return responseAttrs; } ? @Override public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException { if (actionName.equals("sayHello")) { return "Hello, " + name + "!"; } else { throw new UnsupportedOperationException("Operation '" + actionName + "' not supported"); } } ? @Override public MBeanInfo getMBeanInfo() { MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[]{ new MBeanAttributeInfo("Name", "java.lang.String", "Name of the person", true, true, false) }; ? MBeanOperationInfo[] operations = new MBeanOperationInfo[]{ new MBeanOperationInfo("sayHello", "Say hello to the person", null, "java.lang.String", MBeanOperationInfo.ACTION) }; ? return new MBeanInfo(this.getClass().getName(), "Dynamic Hello MBean", attributes, null, operations, null); } ? public static void main(String[] args) throws Exception { DynamicHello dynamicHello = new DynamicHello(); MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("com.example:type=DynamicHello"); mbs.registerMBean(dynamicHello, name); Thread.sleep(Long.MAX_VALUE); } }
在這個(gè)示例中,我們實(shí)現(xiàn)了 DynamicMBean
接口,并重寫了它的方法來提供 MBean 的屬性和操作。動(dòng)態(tài) MBean 允許在運(yùn)行時(shí)確定其屬性和操作,因此我們需要在實(shí)現(xiàn)中動(dòng)態(tài)地處理屬性的獲取、設(shè)置和操作的調(diào)用。
在 getMBeanInfo()
方法中,我們定義了 MBean 的元數(shù)據(jù)信息,包括屬性、操作和描述信息。在 main()
方法中,我們創(chuàng)建了 DynamicHello
的實(shí)例,并將其注冊(cè)到 MBeanServer 中。然后通過 Thread.sleep(Long.MAX_VALUE)
使程序保持運(yùn)行,以便通過 JConsole 或其他 JMX 客戶端來操作該動(dòng)態(tài) MBean。
2.3.Model Bean
Model MBean 的核心是實(shí)現(xiàn) ModelMBean
接口,該接口繼承自 DynamicMBean
接口,因此具有動(dòng)態(tài) MBean 的所有特性,同時(shí)還添加了一些額外的方法用于管理描述符。以下是 ModelMBean
接口的一些重要方法:
setModelMBeanInfo(ModelMBeanInfo mbi)
:設(shè)置 Model MBean 的元數(shù)據(jù)信息,包括屬性、操作和描述符。setManagedResource(Object mr, String mr_type)
:指定 Model MBean 管理的資源對(duì)象及其類型。sendNotification(Notification ntfyObj)
:發(fā)送通知給注冊(cè)的監(jiān)聽器。setAttribute(Attribute attribute)
和getAttribute(String attribute)
:獲取和設(shè)置屬性,這些屬性可以通過描述符來配置。
代碼示例:
import javax.management.*; import javax.management.modelmbean.*; import java.lang.management.ManagementFactory; ? public class SimpleModelMBeanExample { public static void main(String[] args) throws Exception { // 創(chuàng)建 ModelMBeanInfo 對(duì)象 ModelMBeanInfo modelMBeanInfo = createModelMBeanInfo(); ? // 創(chuàng)建 ModelMBean 實(shí)例 ModelMBean modelMBean = createModelMBean(modelMBeanInfo); ? // 創(chuàng)建 MBeanServer MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ? // 創(chuàng)建 ObjectName,用于標(biāo)識(shí) MBean ObjectName name = new ObjectName("com.example:type=SimpleModelMBean"); ? // 注冊(cè) ModelMBean 到 MBeanServer mbs.registerMBean(modelMBean, name); ? // 等待一段時(shí)間,使得可以通過 JConsole 或者其他 JMX 客戶端來操作 MBean Thread.sleep(Long.MAX_VALUE); } ? private static ModelMBeanInfo createModelMBeanInfo() throws Exception { // 創(chuàng)建屬性描述符 Descriptor nameDesc = new DescriptorSupport(); nameDesc.setField("name", "Name"); nameDesc.setField("descriptorType", "attribute"); ? // 創(chuàng)建操作描述符 Descriptor sayHelloDesc = new DescriptorSupport(); sayHelloDesc.setField("name", "sayHello"); sayHelloDesc.setField("descriptorType", "operation"); ? // 創(chuàng)建屬性列表 MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[]{ new MBeanAttributeInfo("Name", "java.lang.String", "Name of the person", true, true, false, nameDesc) }; ? // 創(chuàng)建操作列表 MBeanOperationInfo[] operations = new MBeanOperationInfo[]{ new MBeanOperationInfo("sayHello", "Say hello to the person", null, "java.lang.String", MBeanOperationInfo.ACTION, sayHelloDesc) }; ? // 創(chuàng)建 ModelMBeanInfo ModelMBeanInfo modelMBeanInfo = new ModelMBeanInfoSupport( SimpleModelMBeanExample.class.getName(), "Simple Model MBean Example", attributes, null, operations, null ); ? return modelMBeanInfo; } ? private static ModelMBean createModelMBean(ModelMBeanInfo modelMBeanInfo) throws Exception { // 創(chuàng)建 ModelMBean 實(shí)例 RequiredModelMBean modelMBean = new RequiredModelMBean(); modelMBean.setModelMBeanInfo(modelMBeanInfo); ? // 創(chuàng)建 MBean 實(shí)例 ObjectName name = new ObjectName("com.example:type=SimpleModelMBean"); SimpleModelMBean example = new SimpleModelMBean(); ? // 設(shè)置 MBean 實(shí)例 modelMBean.setManagedResource(example, "ObjectReference"); ? return modelMBean; } }
在這個(gè)示例中,我們首先創(chuàng)建了一個(gè) ModelMBeanInfo
對(duì)象,該對(duì)象描述了 Model MBean 的元數(shù)據(jù)信息,包括屬性和操作。然后,我們創(chuàng)建了一個(gè) ModelMBean
實(shí)例,并將 ModelMBeanInfo
設(shè)置到該實(shí)例中。接著,我們創(chuàng)建了一個(gè) ObjectName
對(duì)象,用于標(biāo)識(shí) MBean,然后將 ModelMBean
實(shí)例注冊(cè)到了 MBeanServer 中。
同時(shí),我們還定義了一個(gè) SimpleModelMBean
類,該類實(shí)現(xiàn)了 Model MBean 管理的資源對(duì)象。在這個(gè)類中,我們可以定義屬性和操作的具體實(shí)現(xiàn)邏輯。
2.4.Dynamic MBean和Model Bean的區(qū)別
其實(shí)Model Bean本來就是繼承自Dynamic MBean的,所以后者有的特點(diǎn),前者也有,其二者本質(zhì)的區(qū)別在于使用場(chǎng)景上:
動(dòng)態(tài)性質(zhì):
Dynamic MBean:Dynamic MBean 的設(shè)計(jì)理念是允許在運(yùn)行時(shí)動(dòng)態(tài)地確定其屬性和操作。它適用于那些在編譯時(shí)無(wú)法確定其管理接口的場(chǎng)景,例如,那些需要根據(jù)外部配置文件或運(yùn)行時(shí)狀態(tài)來確定其管理接口的應(yīng)用程序。
Model MBean:Model MBean 的設(shè)計(jì)理念是通過描述符來描述其管理接口,使得可以在運(yùn)行時(shí)動(dòng)態(tài)地加載和配置 MBean 的屬性和操作。它適用于需要?jiǎng)討B(tài)加載和配置管理接口的場(chǎng)景,例如,根據(jù)不同的環(huán)境或條件來動(dòng)態(tài)地調(diào)整管理接口。
自描述性:
Dynamic MBean:Dynamic MBean 不提供自描述性,開發(fā)人員需要手動(dòng)實(shí)現(xiàn)屬性和操作的獲取和設(shè)置邏輯。它主要關(guān)注于動(dòng)態(tài)性和靈活性,適用于那些需要在運(yùn)行時(shí)動(dòng)態(tài)確定管理接口的場(chǎng)景。
Model MBean:Model MBean 提供了詳細(xì)的元數(shù)據(jù)信息,包括屬性和操作的描述信息,使得管理客戶端可以動(dòng)態(tài)地了解 MBean 的結(jié)構(gòu)和功能。它適用于那些需要自描述性和靈活性的場(chǎng)景,例如,需要通過管理客戶端來動(dòng)態(tài)地了解和操作 MBean 的情況。
適應(yīng)性:
Dynamic MBean:Dynamic MBean 具有較高的適應(yīng)性,可以根據(jù)外部條件或運(yùn)行時(shí)狀態(tài)動(dòng)態(tài)地調(diào)整其管理接口。它適用于那些需要根據(jù)外部條件或運(yùn)行時(shí)狀態(tài)來動(dòng)態(tài)調(diào)整管理接口的場(chǎng)景。
Model MBean:Model MBean 具有較高的適應(yīng)性,可以根據(jù)不同的環(huán)境或條件動(dòng)態(tài)地調(diào)整管理接口。它適用于那些需要根據(jù)不同的部署環(huán)境或運(yùn)行時(shí)條件來動(dòng)態(tài)地配置 MBean 的屬性和操作的場(chǎng)景。
2.5.MXBean
在 Java 中,一切都被視為對(duì)象,而 JMX 則提供了一種標(biāo)準(zhǔn)化的方式來監(jiān)控和管理 Java 程序的運(yùn)行時(shí)狀態(tài)、性能指標(biāo)以及運(yùn)行環(huán)境。而MXBean其實(shí)就是專門用于管理和監(jiān)控這其中一些標(biāo)準(zhǔn)化類型的對(duì)象的。什么叫標(biāo)準(zhǔn)化的類型對(duì)象?其實(shí)就是一些定量的指標(biāo),例如內(nèi)存使用情況、線程信息、操作系統(tǒng)屬性等。這些MBean是拿來即用的。
Java 平臺(tái)中有一些預(yù)定義的 MXBean,例如 MemoryMXBean
、ThreadMXBean
、OperatingSystemMXBean
等,用于管理和監(jiān)控 JVM 的內(nèi)存、線程、操作系統(tǒng)屬性等。
代碼示例:
import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryUsage; ? public class MXBeanExample { public static void main(String[] args) { // 獲取 MemoryMXBean 實(shí)例 MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); ? // 獲取堆內(nèi)存使用情況 MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage(); System.out.println("Heap Memory Usage:"); System.out.println(" Init: " + heapMemoryUsage.getInit() / (1024 * 1024) + " MB"); System.out.println(" Used: " + heapMemoryUsage.getUsed() / (1024 * 1024) + " MB"); System.out.println(" Committed: " + heapMemoryUsage.getCommitted() / (1024 * 1024) + " MB"); System.out.println(" Max: " + heapMemoryUsage.getMax() / (1024 * 1024) + " MB"); ? // 獲取非堆內(nèi)存使用情況 MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage(); System.out.println("Non-Heap Memory Usage:"); System.out.println(" Init: " + nonHeapMemoryUsage.getInit() / (1024 * 1024) + " MB"); System.out.println(" Used: " + nonHeapMemoryUsage.getUsed() / (1024 * 1024) + " MB"); System.out.println(" Committed: " + nonHeapMemoryUsage.getCommitted() / (1024 * 1024) + " MB"); System.out.println(" Max: " + nonHeapMemoryUsage.getMax() / (1024 * 1024) + " MB"); } }
可以自定義MXBean嗎?當(dāng)然可以。
自定義 MXBean 主要包括兩個(gè)步驟:
定義接口:首先,需要定義一個(gè) Java 接口來描述 MXBean 的管理接口。這個(gè)接口中定義了一組屬性和操作,用于描述被管理的對(duì)象的狀態(tài)和行為。
實(shí)現(xiàn)類:然后,需要編寫一個(gè)實(shí)現(xiàn)類來實(shí)現(xiàn)定義的接口。在實(shí)現(xiàn)類中,需要提供屬性和操作的具體實(shí)現(xiàn)邏輯,以及可能需要的管理邏輯。
代碼示例:
// 定義 MXBean 接口 public interface MyMXBean { // 屬性:名稱 String getName(); void setName(String name); // 操作:打印消息 void printMessage(String message); } ? // 實(shí)現(xiàn)類 public class MyMXBeanImpl implements MyMXBean { private String name; // 實(shí)現(xiàn)屬性的 getter 和 setter 方法 @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } // 實(shí)現(xiàn)操作的方法 @Override public void printMessage(String message) { System.out.println(message); } } ? // 在管理應(yīng)用程序中注冊(cè)和使用自定義的 MXBean public class MyMXBeanRegistration { public static void main(String[] args) throws Exception { // 創(chuàng)建 MXBean 實(shí)例 MyMXBean mxBean = new MyMXBeanImpl(); // 注冊(cè) MXBean 到 MBeanServer MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("com.example:type=MyMXBean"); mbs.registerMBean(mxBean, name); // 等待一段時(shí)間,使得可以通過 JConsole 或者其他 JMX 客戶端來操作 MXBean Thread.sleep(Long.MAX_VALUE); } }
在這個(gè)示例中,我們定義了一個(gè)名為 MyMXBean
的接口,包含了一個(gè)屬性 name
和一個(gè)操作 printMessage
。然后,我們編寫了一個(gè)實(shí)現(xiàn)類 MyMXBeanImpl
,實(shí)現(xiàn)了這個(gè)接口,并提供了屬性和操作的具體實(shí)現(xiàn)邏輯。最后,我們?cè)诠芾響?yīng)用程序中注冊(cè)和使用了這個(gè)自定義的 MXBean。
2.6.Open Bean
與傳統(tǒng)的 Standard MBean 和 Dynamic MBean 不同,Open MBean 不需要預(yù)先定義接口,而是使用開放式的數(shù)據(jù)類型和操作來描述 MBean 的管理接口,使得可以更靈活地適應(yīng)各種場(chǎng)景和需求。
代碼示例:
import javax.management.*; import javax.management.openmbean.*; ? public class OpenMBeanExample { public static void main(String[] args) throws Exception { // 創(chuàng)建 OpenType OpenType<String> stringType = SimpleType.STRING; OpenType<Integer> integerType = SimpleType.INTEGER; ? // 創(chuàng)建 OpenMBeanAttributeInfo OpenMBeanAttributeInfoSupport nameAttrInfo = new OpenMBeanAttributeInfoSupport( "Name", "Name of the person", stringType, true, false, false ); OpenMBeanAttributeInfoSupport ageAttrInfo = new OpenMBeanAttributeInfoSupport( "Age", "Age of the person", integerType, true, false, false ); ? // 創(chuàng)建 OpenMBeanOperationInfo OpenMBeanParameterInfo[] params = new OpenMBeanParameterInfo[]{}; OpenMBeanOperationInfoSupport sayHelloOpInfo = new OpenMBeanOperationInfoSupport( "sayHello", "Say hello to the person", params, stringType, OpenMBeanOperationInfo.ACTION ); ? // 創(chuàng)建 OpenMBeanInfo OpenMBeanInfoSupport mbeanInfo = new OpenMBeanInfoSupport( SimpleOpenMBean.class.getName(), "Simple Open MBean Example", new OpenMBeanAttributeInfo[]{nameAttrInfo, ageAttrInfo}, null, new OpenMBeanOperationInfo[]{sayHelloOpInfo}, null ); ? // 創(chuàng)建 OpenMBean 實(shí)例 SimpleOpenMBean mbean = new SimpleOpenMBean("John", 30); ? // 創(chuàng)建 MBeanServer MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ? // 創(chuàng)建 ObjectName,用于標(biāo)識(shí) MBean ObjectName name = new ObjectName("com.example:type=SimpleOpenMBean"); ? // 注冊(cè) OpenMBean 到 MBeanServer mbs.registerMBean(mbean, name); ? // 等待一段時(shí)間,使得可以通過 JConsole 或者其他 JMX 客戶端來操作 MBean Thread.sleep(Long.MAX_VALUE); } } ? // 實(shí)現(xiàn) OpenMBean public class SimpleOpenMBean implements OpenMBean { private String name; private int age; ? public SimpleOpenMBean(String name, int age) { this.name = name; this.age = age; } ? @Override public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { if (attribute.equals("Name")) { return name; } else if (attribute.equals("Age")) { return age; } else { throw new AttributeNotFoundException("Attribute " + attribute + " not found"); } } ? @Override public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { throw new UnsupportedOperationException("setAttribute not supported"); } ? @Override public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException { if (actionName.equals("sayHello")) { return "Hello, " + name + "!"; } else { throw new UnsupportedOperationException("Operation " + actionName + " not supported"); } } ? @Override public MBeanInfo getMBeanInfo() { // 實(shí)現(xiàn) OpenMBean 接口的 getMBeanInfo 方法,返回 MBean 的元數(shù)據(jù)信息 return null; } }
3.控制臺(tái)
JDK自帶了一個(gè)JMX的控制臺(tái)JConsole,啟動(dòng)后選擇進(jìn)程,就能看到相應(yīng)程序中的MBean。
到此這篇關(guān)于JAVA監(jiān)控JMX的使用的文章就介紹到這了,更多相關(guān)JAVA監(jiān)控JMX內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringMVC如何接收參數(shù)各種場(chǎng)景
這篇文章主要介紹了SpringMVC如何接收參數(shù)各種場(chǎng)景,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11SpringBoot的配置文件(properties與yml)使用方法
配置文件中的配置類型有兩類,一類是系統(tǒng)配置項(xiàng),這種配置的格式都是固定的,是給系統(tǒng)使用的,另一種是用戶自定義配置,用戶可以隨意地規(guī)定配置項(xiàng)的格式,又用戶自行去設(shè)置和讀取,這篇文章主要介紹了SpringBoot的配置文件(properties與yml)使用方法,需要的朋友可以參考下2023-08-08java 對(duì)稱加密算法實(shí)現(xiàn)詳解
這篇文章主要介紹了java 對(duì)稱加密算法實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07使用java API實(shí)現(xiàn)zip遞歸壓縮和解壓文件夾
這篇文章主要介紹了使用java API實(shí)現(xiàn)zip遞歸壓縮文件夾及解壓,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08微信開發(fā)準(zhǔn)備第一步 Maven倉(cāng)庫(kù)管理新建WEB項(xiàng)目
這篇文章主要為大家詳細(xì)介紹了微信開發(fā)準(zhǔn)備第一步,Maven倉(cāng)庫(kù)管理新建WEB項(xiàng)目,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04java冷知識(shí):javac AbstractProcessor詳解
這篇文章主要介紹了java冷知識(shí):javac AbstractProcessor詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11