【JAVA】基于JMXMP协议的JMX实战

JMXMP简单介绍

JMXMP(Java Management Extensions Message Protocol)是Java Management Extensions (JMX) 技术中用于远程通信的一种协议。它定义了一种基于TCP/IP的二进制消息格式,用于在JMX客户端和JMX代理(或服务器)之间交换JMX操作。

使用的JDK1.8

开启jmx(JMXMP协议)

jmxmp并非java的标准包中的内容,无论是客户端还是服务端,都需要单独引入其jar。

        <dependency>
            <groupId>org.glassfish.external</groupId>
            <artifactId>opendmk_jmxremote_optional_jar</artifactId>
            <version>1.0-b01-ea</version>
        </dependency>

服务端代码

  1. 与平时的rmi区别在于,需要额外启动一个JMXConnectorServer,这个服务会常驻,用来接受和转发客户端的请求。
import javax.management.*;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.lang.management.ManagementFactory;

/**
 * @version 1.0
 */
public class JMXServer {
    public static void main(String[] args) throws InterruptedException, IOException {
        //获取MBean Server
        MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
        
        // 让服务端JVM支持jmxmp需要开启jmxmp的JMXConnectorServer
        // 设置JMXMP连接器地址
        JMXServiceURL url = new JMXServiceURL("jmxmp", "localhost", 1099);
        // 创建JMXMP连接器服务器并启动
        JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, platformMBeanServer);
        cs.start();
        
        //创建【实现类】服务
        MyMemory myMemory = new MyMemory();
        myMemory.setTotal(100L);
        myMemory.setUsed(20L);
        //注册服务到MBean Server
        ObjectName objectName = new ObjectName("com.example.test.bean:type=myMemory");
        platformMBeanServer.registerMBean(myMemory, objectName);
        while (true) {
            Thread.sleep(5000);
            System.out.println("alive...");
        }
    }
}

可以在开启服务后注册MBean并操作其中的属性值

        //创建【实现类】服务
        MyMemory myMemory = new MyMemory();
        myMemory.setTotal(100L);
        myMemory.setUsed(20L);
        //注册服务到MBean Server
        ObjectName objectName = new ObjectName("com.example.test.bean:type=myMemory");
        platformMBeanServer.registerMBean(myMemory, objectName);
启动服务端的时候需要增加VM选项

开启jmx

-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

客户端代码

查询内置MemoryPool情况

import javax.management.*;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @version 1.0
 */
public class JMXClient {

    public static void main(String[] args) throws IOException, MalformedObjectNameException, ReflectionException, InstanceNotFoundException, IntrospectionException, AttributeNotFoundException, MBeanException {
        // JMX Service URL指向JMXMP协议的服务端地址
        JMXServiceURL jmxServiceURL = new JMXServiceURL("jmxmp", "127.0.0.1", 1099);

        // 创建连接
        Map<String, Object> environment = new HashMap<>();
        // 如果需要认证,可以在此处设置用户名和密码
        // environment.put("jmx.remote.credentials", new String[] { "user", "password" });
        JMXConnector connector = JMXConnectorFactory.connect(jmxServiceURL, environment);

        // 连接成功后,可以获取MBeanServerConnection来进行管理操作
        MBeanServerConnection mbeanServerConnection = connector.getMBeanServerConnection();
        ObjectName objectName = new ObjectName("java.lang:type=MemoryPool,name=*");

        Set<ObjectName> objectNames = mbeanServerConnection.queryNames(objectName, null);
        for (ObjectName name : objectNames) {
            System.out.println("name=" + name);
            MBeanInfo minfo = mbeanServerConnection.getMBeanInfo(name);
            MBeanAttributeInfo[] beanAttributeInfos = minfo.getAttributes();
            Object value;
            for (MBeanAttributeInfo attributeInfo : beanAttributeInfos) {
                try {
                    value = mbeanServerConnection.getAttribute(name, attributeInfo.getName());
                    System.out.println(attributeInfo.getName() + " " + value);
                } catch (Exception e) {
                    System.out.println(attributeInfo.getName() + " 其值不可用");
                }
            }
        }

        // 使用完成后关闭连接
        connector.close();
    }
}

查询自定义com.example.test.bean:type=myMemory情况

import javax.management.*;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @version 1.0
 */
public class JMXClient {

    public static void main(String[] args) throws IOException, MalformedObjectNameException, ReflectionException, InstanceNotFoundException, IntrospectionException, AttributeNotFoundException, MBeanException {
        // JMX Service URL指向JMXMP协议的服务端地址
        JMXServiceURL jmxServiceURL = new JMXServiceURL("jmxmp", "127.0.0.1", 1099);

        // 创建连接
        Map<String, Object> environment = new HashMap<>();
        // 如果需要认证,可以在此处设置用户名和密码
        // environment.put("jmx.remote.credentials", new String[] { "user", "password" });
        JMXConnector connector = JMXConnectorFactory.connect(jmxServiceURL, environment);

        // 连接成功后,可以获取MBeanServerConnection来进行管理操作
        MBeanServerConnection mbeanServerConnection = connector.getMBeanServerConnection();
        ObjectName objectName = new ObjectName("com.example.test.bean:type=*");

        Set<ObjectName> objectNames = mbeanServerConnection.queryNames(objectName, null);
        for (ObjectName name : objectNames) {
            System.out.println("name=" + name);
            MBeanInfo minfo = mbeanServerConnection.getMBeanInfo(name);
            MBeanAttributeInfo[] beanAttributeInfos = minfo.getAttributes();
            Object value;
            for (MBeanAttributeInfo attributeInfo : beanAttributeInfos) {
                try {
                    value = mbeanServerConnection.getAttribute(name, attributeInfo.getName());
                    System.out.println(attributeInfo.getName() + " " + value);
                } catch (Exception e) {
                    System.out.println(attributeInfo.getName() + " 其值不可用");
                }
            }
        }

        // 使用完成后关闭连接
        connector.close();
    }
}

JMX内置的JVM资源检测

资源接口监测的资源ObjectName
ClassLoadingMXBean类加载name=java.lang:type=ClassLoading
CompilationMXBean汇编系统name=java.lang:type=Compilation
GarbageCollectorMXBean垃圾回收name=java.lang:type=GarbageCollector,name=XXX
MemoryManagerMXBean内存管理name=java.lang:type= MemoryManager,name=XXX
MemoryPoolMXBean内存池管理name=java.lang:type=MemoryPool,name=XXX
ThreadMXBean线程情况name=java.lang:type=Threading
RuntimeMXBean运行时情况name=java.lang:type=Runtime
OperatingSystemMXBean操作系统情况name=java.lang:type=OperatingSystem

彩蛋

当rmi协议不可用的时候,可以使用jmxmp协议。

rmi为啥不可用了?

  • 低版本的JBOSS/wildfly(8.2以下)的配置文件中,没有主动开启rmi时,或者无法开启时。JBOSS和wildfly机器上对其他服务进行jmx访问(rmi协议)。需要增加中配置后才能正常使用。配置~/wildfly/modules/system/layers/base/sun/jdk/main/module.xml中增加<path name="com/sun/jndi/url/rmi"/>
  • 防火墙禁止了rmi协议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顧棟

若对你有帮助,望对作者鼓励一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值