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等,每種類型適用于不同的場景。
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):它是最簡單的一種 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 類型。它定義了一種簡單的 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ū)別在于使用場景上:
動(dòng)態(tài)性質(zhì):
Dynamic MBean:Dynamic MBean 的設(shè)計(jì)理念是允許在運(yùn)行時(shí)動(dòng)態(tài)地確定其屬性和操作。它適用于那些在編譯時(shí)無法確定其管理接口的場景,例如,那些需要根據(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)加載和配置管理接口的場景,例如,根據(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)確定管理接口的場景。
Model MBean:Model MBean 提供了詳細(xì)的元數(shù)據(jù)信息,包括屬性和操作的描述信息,使得管理客戶端可以動(dòng)態(tài)地了解 MBean 的結(jié)構(gòu)和功能。它適用于那些需要自描述性和靈活性的場景,例如,需要通過管理客戶端來動(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)整管理接口的場景。
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 的屬性和操作的場景。
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)各種場景和需求。
代碼示例:
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)文章
SpringBoot的配置文件(properties與yml)使用方法
配置文件中的配置類型有兩類,一類是系統(tǒng)配置項(xiàng),這種配置的格式都是固定的,是給系統(tǒng)使用的,另一種是用戶自定義配置,用戶可以隨意地規(guī)定配置項(xiàng)的格式,又用戶自行去設(shè)置和讀取,這篇文章主要介紹了SpringBoot的配置文件(properties與yml)使用方法,需要的朋友可以參考下2023-08-08
java 對(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倉庫管理新建WEB項(xiàng)目
這篇文章主要為大家詳細(xì)介紹了微信開發(fā)準(zhǔn)備第一步,Maven倉庫管理新建WEB項(xiàng)目,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
java冷知識(shí):javac AbstractProcessor詳解
這篇文章主要介紹了java冷知識(shí):javac AbstractProcessor詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11

