使用 JMX 监控和管理 Java 程序(二)

简介: 使用 JMX 监控和管理 Java 程序(二)

4. JMX 的具体使用

在资源管理 MBean 部分已经演示了使用 JMX 获取 JVM 运行信息,那么如果想要自定义一个资源 MBean 呢?

下面通过一个例子,模拟一个内存资源 MBean,最后对它进行远程管理。

4.1. 编写资源管理 MBean

MBean 的编写必须遵守 JMX 的设计规范,MBean 很像一个特殊的 Java Bean,它需要一个接口和一个实现类。MBean 资源接口总是以 MBean 或者 MXBean 结尾实现类则要以接口去掉 MBean 或 MXBean 之后的名字来命名

编写一个内存资源管理 MBean 接口,定义如下:

package com.wdbyte.jmx;
/**
 * @author https://www.wdbyte.com
 */
public interface MyMemoryMBean {
    long getTotal();
    void setTotal(long total);
    long getUsed();
    void setUsed(long used);
    String doMemoryInfo();
}

然后实现这个接口:

package com.wdbyte.jmx;
/**
 * @author https://www.wdbyte.com
 */
public class MyMemory implements MyMemoryMBean {
    private long total;
    private long used;
    @Override
    public long getTotal() {
        return total;
    }
    @Override
    public void setTotal(long total) {
        this.total = total;
    }
    @Override
    public long getUsed() {
        return used;
    }
    @Override
    public void setUsed(long used) {
        this.used = used;
    }
    @Override
    public String doMemoryInfo() {
        return String.format("使用内存: %dMB/%dMB", used, total);
    }
}

这个例子在 MyMemory.java 中只有两个 long  基本类型属性,所以接口是以 MBean 结尾。如果资源实现类中的属性是自定义实体类的引用,那么接口就需要以 MXBean 结尾。

这样就完成了线程数量资源 MBean 的创建,其中 totalused  是资源属性,doMemoryInfo 是资源操作方法。

4.2. 注册资源到 MBean Server

通过上面的 JMX 架构图,我们知道 MBean 资源需要注册到 MBean Server 进行代理才可以暴露给外部进行调用,所以我们想要通过远程管理我们自定义的 MyMemory 资源,需要先进行资源代理。

package com.wdbyte.jmx;
import java.lang.management.ManagementFactory;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
/**
 * @author https://www.wdbyte.com
 */
public class MyMemoryManagement {
    public static void main(String[] args) throws MalformedObjectNameException, NotCompliantMBeanException,
        InstanceAlreadyExistsException, MBeanRegistrationException, InterruptedException {
        // 获取 MBean Server
        MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
        MyMemory myMemory = new MyMemory();
        myMemory.setTotal(100L);
        myMemory.setUsed(20L);
        // 注册
        ObjectName objectName = new ObjectName("com.wdbyte.jmx:type=myMemory");
        platformMBeanServer.registerMBean(myMemory, objectName);
        while (true) {
            // 防止进行退出
            Thread.sleep(3000);
            System.out.println(myMemory.doMemoryInfo());
        }
    }
}

启动后可以看到控制台每隔三秒打印我们自定义的内存信息。

使用内存: 20MB/100MB
使用内存: 20MB/100MB

不加任何 JVM 参数启动 Java 程序,JMX 只能在当前机器访问,如果想要通过网络在真正的远程访问,那么在启动时需要指定当前机器 ip 和开放的端口。

$ java -Dcom.sun.management.jmxremote=true \  # 开启远程访问
-Dcom.sun.management.jmxremote.port=8398 \  # 自定义 JMX 端口
-Dcom.sun.management.jmxremote.ssl=false \  # 是否使用 SSL 协议,生产环境一定要开启
-Dcom.sun.management.jmxremote.authenticate=false \ # 是否需要认证,生产环境一定要开启
-Djava.rmi.server.hostname=150.158.2.56 YourClass.java # 当前机器 ip

4.3. 远程管理 jconsole

jconsole 是 Java 自带的基于 JMX 技术的监控管理工具,如果已经配置了 JDK 环境变量,可以直接控制台通过 jconsole 命令启动。

微信图片_20220414180323.png

启动 jconsole 后会列出当前机器上的 Java 进行,这里选择自己要监控的 Java 进程进行监控,连接后会提示不安全的协议,是因为 Java 程序默认启动是不会配置 HTTPS 协议的原因。

连接后可以看到多维度的 JVM 监控信息,这些信息都是通过读取 JVM 资源 MBean 信息得到的。

微信图片_20220414180327.png

在下面这个页面列举了线程信息,注意最下面的线程信息,可以看到 RMI TCP 线程,这里也证明了 JMX 默认通过 RMI 协议进行远程管理。

微信图片_20220414180330.png

在 MBean 页面可以浏览所有可管理的 MBean 信息,也可以看到我们自定义的 com.wdbyte.jmx 中的内存信息,甚至可以直接修改其中的 used 变量。

微信图片_20220414180335.png

修改后控制台日志立即发生变化,可以看到已经修改成功。

使用内存: 20MB/100MB
使用内存: 20MB/100MB
使用内存: 20MB/100MB
使用内存: 30MB/100MB

在操作中可以调用 doMemoryInfo 方法,调用后可以看到返回值中使用内存已经由启动时的 20MB 更新为 30MB。

微信图片_20220414180338.png

一如既往,当前文章中的代码示例都存放在 github.com/niumoo/JavaNotes.


相关文章
|
1月前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
112 38
|
1月前
|
IDE Java 编译器
开发 Java 程序一定要安装 JDK 吗
开发Java程序通常需要安装JDK(Java Development Kit),因为它包含了编译、运行和调试Java程序所需的各种工具和环境。不过,某些集成开发环境(IDE)可能内置了JDK,或可使用在线Java编辑器,无需单独安装。
68 1
|
24天前
|
SQL 安全 Java
Java 异常处理:筑牢程序稳定性的 “安全网”
本文深入探讨Java异常处理,涵盖异常的基础分类、处理机制及最佳实践。从`Error`与`Exception`的区分,到`try-catch-finally`和`throws`的运用,再到自定义异常的设计,全面解析如何有效管理程序中的异常情况,提升代码的健壮性和可维护性。通过实例代码,帮助开发者掌握异常处理技巧,确保程序稳定运行。
37 0
|
1月前
|
SQL 监控 Java
Java连接池技术的最新发展,包括高性能与低延迟、智能化管理与监控、扩展性与兼容性等方面
本文探讨了Java连接池技术的最新发展,包括高性能与低延迟、智能化管理与监控、扩展性与兼容性等方面。同时,结合最佳实践,介绍了如何选择合适的连接池库、合理配置参数、使用监控工具及优化数据库操作,以实现高效稳定的数据库访问。示例代码展示了如何使用HikariCP连接池。
20 2
|
1月前
|
Prometheus 监控 Cloud Native
JAVA线程池监控以及动态调整线程池
【10月更文挑战第22天】在 Java 中,线程池的监控和动态调整是非常重要的,它可以帮助我们更好地管理系统资源,提高应用的性能和稳定性。
97 4
|
1月前
|
Prometheus 监控 Cloud Native
在 Java 中,如何使用线程池监控以及动态调整线程池?
【10月更文挑战第22天】线程池的监控和动态调整是一项重要的任务,需要我们结合具体的应用场景和需求,选择合适的方法和策略,以确保线程池始终处于最优状态,提高系统的性能和稳定性。
256 2
|
2月前
|
Java Maven 数据安全/隐私保护
如何实现Java打包程序的加密代码混淆,避免被反编译?
【10月更文挑战第15天】如何实现Java打包程序的加密代码混淆,避免被反编译?
156 2
|
2月前
|
安全 Java Linux
java程序设置开机自启
java程序设置开机自启
157 1