JMX的快速入门与使用

JMX应用场景

用来监控JVM内各种对象的信息。一个经典场景就是,某一天我们忽然被前方告知,业务大面积瘫痪,这时经过排查,发现由于bug导致数据库连接使用完了没有被释放,导致后续业务没有可用的数据库连接而超时报错。

假如我们使用JMX来监控我们系统中数据库连接池的信息,当数据库连接池出现短时间内连接被大量使用,这个时候可以搭配我们的监控报警系统(如Nagios)在问题未出现之前就进行响应,可以极大避免上述情况的发生

MXBean 和 MBean的区别

JMX中分为MBean和MXBean,这里只给出MXBean的例子,如有兴趣,参考下面官方文档获取有关MBean的内容

二者的区别

一句话简单概括二者的区别:MXBean中可以包含对象,而MBean中只能包含基本类型和String。在jconsole中MXBean中的对象可以正常显示,而MBean中的对象显示不出来

更多有关MBean的实践,可以参考各种开源框架里对JMX的支持。如Log4j2中的LoggerContextAdminMBean、ContextSelectorAdminMBean

JMX使用

使用JMX很简单,基本分为以下几步

定义一个MXBean

@MXBean
public interface MyMXBean{

    User getUser();
    
    String getName();

    void setName(String name);

    void logMessage();

}

这里有两种写法

  • 直接使用@MXBean注解
  • 不使用注解,但是接口名字必须以MXBean结尾

其他注意事项

  • 在jconsole中显示的名字是Name,也就是getName去掉get前缀,如果是getname,那么在jconsole中显示的名字就是name
  • 在MXBean中可以查看我们自定义的对象,如这里的User.但是在MBean中是观察不到的。原因是MXBean中的User属性包装成了CompositeDataSupport对象
  • jconsole中看到的属性对应的是在MXBean实现类中定义的,对属性的具体操作方法get/set则是在MXBean中定义的,二者通过接口中实现的方法进行关联,如果只有属性而接口中没有和这个属性相关的方法,那么jconsole中是看不到这个属性的
  • jconsole中看到的操作则是不涉及当前类中的属性
  • 【属性】默认的方法名字是get和set和is*去掉前缀。如果提供了set和get方法,那么该属性在jconsole中的属性【那里】是可以直接编辑,然后【刷新】的
    一个简单的方法是,如果属性点开右边显示部分是蓝色,那么基本可以是编辑的。也说明这个属性有setA和getA方法。如果是灰色的,说明不可编辑。只有getA方法
  • 【操作】如果方法名字不是上述的那几种,则为操作。也可以是同为set*方法,但是有多个参数。参考org.apache.logging.log4j.core.jmx.LoggerContextAdminMBean#setConfigText

实现该MXBean

public class MyMXBeanImpl implements MyMXBean {

    private String name = "jack";

    private User user = User.builder().name("jack").password(888888L).used(false).build();;

    @Override
    public User getUser() {
        return user;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    /**
     * JMX 操作示例
     */
    @Override
    public void logMessage() {
        log.info("log message");
    }
}

将MXBean注册到JMX中去

@Component
public class JMXRegister {
  
    @PostConstruct
    @SneakyThrows
    public void registerMXBeans() {
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        // ObjectName的完整写法可参考 javax.management.ObjectName的注释 
        ObjectName mxbeanName = new ObjectName("com.demo.jmx.mbean:type=MyMXBeanImpl, name=custom");
        MyMXBeanImpl myMXBean = new MyMXBeanImpl();
        mbs.registerMBean(myMXBean, mxbeanName);
    }
}

可以看到这里很简单,就是new了一个我们需要监控的Bean,然后给它一个名字。其中ObjectName的写法为

xxx:type=MXBean接口的实现类的类名, name=自定义的名字

使用Jconsole监控

启动应用之后,启动Jconsole,启动之后找到我们应用的进程名字,点击连接。连接进去之后在MBean那里即可找到刚才自定义的MXBean
可以看到属性操作
在这里插入图片描述
属性值CompositeDataSupport上双击可以看到对象内部的属性,再次双击则隐藏
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在具体属性下面,可以进行查看和修改具体属性的具体值

注意 : 具体属性的值能不能修改取决去属性是由什么修饰,如果是由final修饰,那肯定是修改不了的

这里可以看到我们的MXBean在JMX中,它的ObjectName到底是什么。这一点很有用,当我们想要监控一个第三方类库中的MXBean,但是不知道它在JMX中叫什么时,可以在本地启动代码,然后在Jconsole中找到它
在这里插入图片描述

如果想要连接远程JMX,则可以使用类似以下这种写法

service:jmx:rmi://192.168.30.10:1234/jndi/rmi://192.168.30.10:2344/jmxrmi
service:jmx:rmi://<TARGET_MACHINE>:<JMX_RMI_SERVER_PORT>/jndi/rmi://<TARGET_MACHINE>:<RMI_REGISTRY_PORT>/jmxrmi

这样一看就清晰多了吧。如果还不理解,可以看Stackoverflow关于JMX的url的解释

JMX官方文档

其他框架用到JMX的示例

JMX使用的身影可以在很多地方都可以找到,这里列举两个

  • SpringBoot中用到的SpringApplicationAdminMXBean
  • Java内部的MemoryMXBean

源码地址

  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值