JMX架构由三个主要组件构成:
javax.management.DynamicMBean
。JMX标准中将MBean分为以下几种:
Model MBean(模型 MBean):模型 MBean 是一种特殊的 MBean,它通过描述符来描述其管理接口,可以在运行时动态地配置其属性和操作。模型 MBean 可以通过 XML 或者通过程序动态地加载描述符。
MXBean:MXBean 是一种专门用于 JMX 的 MBean 类型。它定义了一种简单的 Java 接口和实现约定,用于描述 MBean 的属性和操作,同时这些接口和实现类遵循 Java Bean 的命名约定。MXBean 在 JMX 中用于管理特定类型的对象,例如内存使用情况、线程信息等。
Standard MBean按照JMX的命名规范来定义接口然后注册到MBean Server中,MBean就能被JMX的client端访问到。
public interface HelloMBean {
String getName();
void setName(String name);
void sayHello();
}
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 {
// 创建标准 MBean 实例
HelloMBean helloMBean = new Hello();
// 创建 MBeanServer
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
// 创建 ObjectName,用于标识 MBean
ObjectName name = new ObjectName("com.example:type=Hello");
// 注册 MBean 到 MBeanServer
mbs.registerMBean(helloMBean, name);
// 等待一段时间,使得可以通过 JConsole 或者其他 JMX 客户端来操作 MBean
Thread.sleep(Long.MAX_VALUE);
}
}
1. 引入依赖
org.springframework.boot spring-boot-starter-actuator
2. yml 配置
spring: jmx: enabled: true
3. 注解实现Mbean 类
@Component
@ManagedResource(objectName = "bean:name=myBeanTest", description = "My Managed Bean")
public class MbeanTest {
private String name;
@ManagedAttribute(description = "The Name")
public String getName() {
return name;
}
@ManagedAttribute(description = "The Name")
public void setName(String name) {
this.name = name;
}
@ManagedOperation(description = "Say Hello")
public String sayHello() {
return "Hello, " + name;
}
}
动态 MBean 的核心是实现 DynamicMBean 接口,该接口定义了一组方法,用于动态地获取和设置 MBean 的属性,执行 MBean 的操作,以及获取 MBean 的元数据信息。以下是 DynamicMBean 接口的几个核心方法:
@Component
@ManagedResource(objectName = "bean:name=DynamicMBeanTest", description = "My Dynamic Bean")
public class DynamicMBeanTest 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);
}
}
Model MBean 的核心是实现 ModelMBean
接口,该接口继承自 DynamicMBean
接口,因此具有动态 MBean 的所有特性,同时还添加了一些额外的方法用于管理描述符。
public class ModelMBeanTest {
private static ModelMBeanInfo createModelMBeanInfo() throws Exception {
// 创建属性描述符
Descriptor nameDesc = new DescriptorSupport();
nameDesc.setField("name", "Name");
nameDesc.setField("descriptorType", "attribute");
// 创建操作描述符
Descriptor sayHelloDesc = new DescriptorSupport();
sayHelloDesc.setField("name", "sayHello");
sayHelloDesc.setField("descriptorType", "operation");
// 创建属性列表
ModelMBeanAttributeInfo[] attributes = new ModelMBeanAttributeInfo[]{
new ModelMBeanAttributeInfo("Name", "java.lang.String", "Name of the person", true, true, false, nameDesc)
};
// 创建操作列表
ModelMBeanOperationInfo[] operations = new ModelMBeanOperationInfo[]{
new ModelMBeanOperationInfo("sayHello", "Say hello to the person", null, "java.lang.String", MBeanOperationInfo.ACTION, sayHelloDesc)
};
// 创建 ModelMBeanInfo
ModelMBeanInfo modelMBeanInfo = new ModelMBeanInfoSupport(
ModelMBeanTest.class.getName(),
"Simple Model MBean Example",
attributes,
null,
operations,
null
);
return modelMBeanInfo;
}
private static ModelMBean createModelMBean(ModelMBeanInfo modelMBeanInfo) throws Exception {
// 创建 ModelMBean 实例
RequiredModelMBean modelMBean = new RequiredModelMBean();
modelMBean.setModelMBeanInfo(modelMBeanInfo);
// 创建 MBean 实例
ObjectName name = new ObjectName("com.example:type=SimpleModelMBean");
ModelMBeanTest example = new ModelMBeanTest();
// 设置 MBean 实例
modelMBean.setManagedResource(example, "ObjectReference");
return modelMBean;
}
public static void main(String[] args) throws Exception {
// 创建 ModelMBeanInfo 对象
ModelMBeanInfo modelMBeanInfo = createModelMBeanInfo();
// 创建 ModelMBean 实例
ModelMBean modelMBean = createModelMBean(modelMBeanInfo);
// 创建 MBeanServer
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
// 创建 ObjectName,用于标识 MBean
ObjectName name = new ObjectName("com.example:type=ModelMBeanTest");
// 注册 ModelMBean 到 MBeanServer
mbs.registerMBean(modelMBean, name);
// 等待一段时间,使得可以通过 JConsole 或者其他 JMX 客户端来操作 MBean
Thread.sleep(Long.MAX_VALUE);
}
}
与传统的 Standard MBean 和 Dynamic MBean 不同,Open MBean 不需要预先定义接口,而是使用开放式的数据类型和操作来描述 MBean 的管理接口,使得可以更灵活地适应各种场景和需求。
@Component
public class SimpleOpenMBean extends NotificationBroadcasterSupport {
// Constructor
public SimpleOpenMBean() {
super();
openMBean();
}
// The actual value of the "SimpleProperty" attribute
private int simpleProperty = 0;
// Operation to reset the SimpleProperty
public void reset() {
simpleProperty = 0;
}
public MBeanInfo openMBean() {
OpenMBeanAttributeInfoSupport simplePropertyInfo =
new OpenMBeanAttributeInfoSupport(
"SimpleProperty",
"The SimpleProperty of the SimpleOpenMBean",
SimpleType.INTEGER,
true, // isReadable
true, // isWritable
false); // isIs
OpenMBeanConstructorInfoSupport constructorInfo =
new OpenMBeanConstructorInfoSupport(
"SimpleOpenMBean",
"Constructs a SimpleOpenMBean instance",
new OpenMBeanParameterInfoSupport[]{});
OpenMBeanOperationInfoSupport resetOperationInfo =
new OpenMBeanOperationInfoSupport(
"reset",
"Resets the SimpleProperty to 0",
new OpenMBeanParameterInfoSupport[]{},
SimpleType.VOID,
MBeanOperationInfo.ACTION);
return new OpenMBeanInfoSupport(
SimpleOpenMBean.class.getName(),
"SimpleOpenMBean Description",
new OpenMBeanAttributeInfo[]{simplePropertyInfo},
new OpenMBeanConstructorInfo[]{constructorInfo},
new OpenMBeanOperationInfo[]{resetOperationInfo},
new MBeanNotificationInfo[0]);
}
}
在 Java 中,一切都被视为对象,而 JMX 则提供了一种标准化的方式来监控和管理 Java 程序的运行时状态、性能指标以及运行环境。而MXBean就是专门用于管理和监控这其中一些标准化类型的对象的,例如内存使用情况、线程信息、操作系统属性等。这些MBean是拿来即用的。
平台MXBean是 Java SE 平台提供的一组 MXBean,用于监视和管理 Java VM 以及 Java 运行时环境 (JRE) 的其他组件。每个平台 MXBean 都封装了一部分 Java VM 功能,例如类加载系统、即时 (JIT) 编译系统、垃圾收集器等。可以使用符合 JMX 规范的监视和管理工具显示这些 MXBean 并与之交互,以便您监视和管理这些不同的 VM 功能。Java SE 平台的 JConsole 图形用户界面 (GUI) 就是这样一种监视和管理工具。Java SE 平台提供了一个标准平台 MBean 服务器,这些平台 MXBean 都注册在该服务器中。平台 MBean 服务器还可以注册您希望创建的任何其他 MBean。
public class XMBeanTest {
public static void main(String[] args) {
// 获取内存管理MXBean,用于监控和管理Java虚拟机的内存系统
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
// 获取线程系统MXBean,用于监控和管理Java虚拟机的线程系统
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 获取运行时系统MXBean,用于获取Java虚拟机的运行时信息
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
// 获取操作系统MXBean,用于获取操作系统的相关信息
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
// 获取编译系统MXBean,用于获取Java虚拟机的即时编译器信息
CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();
// 获取Java虚拟机堆内存的使用情况
MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
// 获取Java虚拟机非堆内存的使用情况
MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
// 获取类加载系统的MXBean,用于监控和管理Java虚拟机的类加载系统
ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
// 获取所有内存池的MXBean列表,用于监控和管理Java虚拟机的内存池
List memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
// 获取所有内存管理器的MXBean列表,用于监控和管理Java虚拟机的内存管理器
List memoryManagerMXBeans = ManagementFactory.getMemoryManagerMXBeans();
// 获取所有垃圾收集器的MXBean列表,用于监控和管理Java虚拟机的垃圾收集器
List garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
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");
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");
}
}
MBeanServer
是一个Java对象,它充当JMX代理的核心。它提供了一个注册和管理MBeans的环境。MBeans是遵循特定约定的Java对象,它们暴露了可以被管理的资源或服务。
MBeanServer
允许你注册MBeans,并通过ObjectName来引用它们。每个MBean都有一个唯一的ObjectName,它是MBeanServer
用来识别和管理MBean的关键。MBeanServer
提供了方法来访问MBeans的属性、调用操作、注册和接收通知。MBeanServer
支持远程客户端的连接,从而允许远程管理和监控。MBeanServer
可以通过不同的协议(如RMI、JMS、HTTP等)暴露MBeans。createMBean
或registerMBean
方法,可以将MBean注册到MBeanServer
中。invoke
方法来执行MBean的操作。getAttribute
和setAttribute
方法来读取和修改MBean的属性。MBeanServer
支持事件和通知机制,允许MBeans在特定事件发生时发送通知。MBeanServer
可以作为其他MBeanServer的代理或委托,实现更复杂的管理结构。 在Java应用程序中,通常使用以下方式来创建MBeanServer:
MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer();
如果使用JMX的javax.management.MBeanServerFactory
类
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ManagementFactory.getPlatformMBeanServer()
方法返回的MBeanServer
是Java虚拟机启动时创建的平台MBeanServer。
以下是一些使用MBeanServer
的基本步骤:
MBeanServer
实例。ObjectName
注册MBean到MBeanServer
。MBeanServer
的方法来访问MBean的属性、调用操作或接收通知。// 创建MBeanServer
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
// 创建ObjectName
ObjectName name = new ObjectName("com.example:type=MyMBean");
// 创建MBean实例
MyMBean mbean = new MyMBeanImpl();
// 注册MBean
mBeanServer.registerMBean(mbean, name);
// 调用MBean操作
mBeanServer.invoke(name, "myOperation", new Object[]{}, new String[]{});
// 读取MBean属性
Integer value = (Integer) mBeanServer.getAttribute(name, "MyAttribute");
JMX Agent是指一个运行在Java虚拟机(JVM)中的管理实体,它负责管理一个或多个MBeans(Managed Beans),并提供与外部管理应用程序(如JMX客户端)的通信接口。
一个JMX agent
通常包含以下几个主要组件:
MBeanServer:agent
的核心组件,负责注册和管理MBeans,并提供对MBeans的操作、属性访问和通知的接口。
MBeans:实现具体管理功能的Java对象,它们可以是标准MBeans、动态MBeans、开放MBeans或模型MBeans。
JMX Connector:允许远程管理应用程序通过特定的协议(如RMI、JMXMP、IIOP、HTTP等)连接到agent
。
Service MBean:提供agent
级别的服务,如安全管理、事件处理、监控服务等。
Adaptor:将agent
中的MBeans暴露给不同的管理协议,例如将MBeans通过JMX RMI连接器暴露给远程客户端。
agent
支持本地和远程管理,使得管理员可以通过本地或远程JMX客户端对Java应用程序进行监控和管理。agent
可以将Java应用程序中的服务封装成MBeans,从而便于管理。agent
可以实现访问控制,确保只有授权的管理员可以访问或修改MBeans。agent
支持事件和通知机制,允许MBeans在特定事件发生时发送通知给感兴趣的监听者。agent
也会启动,并创建MBeanServer。agent
管理MBeans,处理来自JMX客户端的请求,发送和接收通知。agent
会进行清理工作,如注销MBeans,关闭连接器等。 创建一个简单的JMX agent
通常涉及以下步骤:
MBeanServer
实例。MBeanServer
。agent
可以接受远程连接。import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class JMXAgent {
public static void main(String[] args) throws Exception {
// 创建MBeanServer
MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer();
// 创建ObjectName
ObjectName name = new ObjectName("com.example:type=MyMBean");
// 创建并注册MBean
MyMBean mbean = new MyMBeanImpl();
mBeanServer.registerMBean(mbean, name);
// 创建JMX服务URL
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
// 创建JMXConnectorServer
JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mBeanServer);
// 启动连接器
connectorServer.start();
// 打印连接信息
System.out.println("JMX Agent is running at: " + url);
}
}
官方文档 : https://docs.oracle.com/javase/tutorial/jmx/overview/index.html
【JMX】JAVA监控的基石-CSDN博客
JMX使用详解-CSDN博客
Java-JMX (官方文档解读)_jmx怎么shiyo-ng-CSDN博客