使用 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.


相关文章
|
9月前
|
安全 Java
Java异常处理:程序世界的“交通规则
Java异常处理:程序世界的“交通规则
409 98
|
10月前
|
监控 Kubernetes Java
使用 New Relic APM 和 Kubernetes Metrics 监控 EKS 上的 Java 微服务
在阿里云AKS上运行Java微服务常遇性能瓶颈与OOMKilled等问题。本文教你通过New Relic实现集群与JVM双层监控,集成Helm部署、JVM代理注入、GC调优及告警仪表盘,打通从节点资源到应用内存的全链路观测,提升排障效率,保障服务稳定。
678 115
|
10月前
|
存储 Java 编译器
对比Java学习Go——程序结构与变量
本节对比了Java与Go语言的基础结构,包括“Hello, World!”程序、代码组织方式、入口函数定义、基本数据类型及变量声明方式。Java强调严格的面向对象结构,所有代码需置于类中,入口方法需严格符合`public static void main(String[] args)`格式;而Go语言结构更简洁,使用包和函数组织代码,入口函数为`func main()`。两种语言在变量声明、常量定义、类型系统等方面也存在显著差异,体现了各自的设计哲学。
356 0
|
11月前
|
人工智能 监控 安全
智慧工地解决方案,java智慧工地程序代码
智慧工地系统融合物联网、AI、大数据等技术,实现对施工现场“人、机、料、法、环”的全面智能监控与管理,提升安全、效率与决策水平。
303 2
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
582 0
|
存储 机器学习/深度学习 监控
如何监控员工的电脑——基于滑动时间窗口的Java事件聚合算法实现探析​
在企业管理场景中,如何监控员工的电脑操作行为是一个涉及效率与合规性的重要课题。传统方法依赖日志采集或屏幕截图,但数据量庞大且实时性不足。本文提出一种基于滑动时间窗口的事件聚合算法,通过Java语言实现高效、低资源占用的监控逻辑,为如何监控员工的电脑提供一种轻量化解决方案。
544 3
|
存储 Java 数据库连接
【YashanDB知识库】Java程序调用存储过程,在提取clob时报YAS-00004
【YashanDB知识库】Java程序调用存储过程,在提取clob时报YAS-00004
|
搜索推荐 Java Android开发
课时146:使用JDT开发Java程序
在 Eclipse 之中提供有 JDT环境可以实现java 程序的开发,下面就通过一些功能进行演示。 项目开发流程
505 0
|
设计模式 监控 网络协议
使用 JMX 监控和管理 Java 程序(一)
使用 JMX 监控和管理 Java 程序
902 0
使用 JMX 监控和管理 Java 程序(一)