Java JMX 监管

JSR 规范系列目录(https://www.cnblogs.com/binarylei/p/10348178.html)

JMX(Java Management Extensions) 技术提供构建分布式、Web、模块化的工具,以及管理和监控设备和应用的动态解决方案。从 Java 5 开始,JMX API 作为 Java 平台的一部分。

一、整体架构

JMX 的整体架构分为三层。设备层(Instrumentation Level)、代理层(Agent Level)、分发层(Distributed Level)。额,如果感觉有点懵,没关系,暂时理解自上而下分为三个层次就可以。

结构图如下:

1.1 设备层

"设备层"定义了信息模型。简单来说就是能被 java 描述出来的一个对象,这些对象成为“管理构件”,简称 MBean

这些 MBean 就是我们要管理的指标,每个 MBean 都可以监控一类信息。

MBean又分为以下几种:

  • Standard MBean(标准 MBeans) 设计和实现最为简单,Bean 的管理 通过接口方法来描述。MXBean 是一种特殊标准 MBean,它使用开放 MBean 的概念,允许通用管理,同时简化编码。
  • Dynamic MBean(动态 MBeans) 必须实现指定的接口,不过它在运行时能让管理接口发挥最大弹性。
  • Open MBean(开放 MBeans) 提供通用管理所依赖的基本数据类型以及用户友好的自描述信息。
  • Model MBean(模型 MBeans) 同样也是动态 MBean,在运行时能够完全可配置和自描述,为动态的设备资源提供带有默认行为的 MBean 泛型类。
  • MXBean

这里以 Standard MBean、Dynamic MBean、MXBean 为例作为入门介绍

(1) Standard MBean(标准 MBeans)

这是最简单的 MBean,通过方法名来管理接口。Standard MBean 的实现依赖于一组特定的命名规范。

规范如下:

  • 定义一个接口,名称为 xxxxMBean 的格式,必须以 MBean 结尾,以 User 为例,接口名为 UserMBean

    定义属性方法,假设 User 含有 id 和 name 属性,那么可以通过定义 getId、setId、getName 和 setName 来控制属性是否可读写,如果只定义了 set 方法,那么该属性可写不可读;如果只定义了 get 方法,那么该属性可读不可写;同时定义,那么就可读可写
  • 定义操作,其他非 get 和 set 方法,可以算是对该对象的操作
  • 接口定义完了,具体实现,需要继承上接口,以 UserMBean 为例,那么该实现也就必须命名为 User,然后实现该接口
  • 补充一点,参数和返回类型只能是简单的引用类型(如 String)和基本数据类型,其他类型编译不会出错,但是结果会稍有不同,稍后验证

(2) Dynamic MBean(动态 MBeans)

这种 MBean 就没有那么多限制,但是有一条硬性规则,必须实现 javax.management.DynamicMBean 接口。所有的属性都在运行时定义的。比较灵活

(3) MXBean

严格上讲,MXBean 这不是 MBean 的一种分类。MXBean 是 MBean 的一种,只是这货有些特殊,较为常用,所以放在一起讲。

规范如下:

  • 实现 xxxMXBean 接口,或者不按照 MXBean 结尾来命名,但是需要加上 @MXBean 的注解
  • 支持各种数据类型,包括自定义类型
  • 其他方法命名规则与 MBean 类似

1.2 代理层

代理层就是用来管理资源的,管理 MBean。代理层的核心模块就是 MBean Server 和一系列附加的 MBean Service。

而 MBean Server 其实就是 MBean 的容器,可以注册 Adapter、Connector、MBean 并且直接管理 MBean

1.3 分发层

这一层主要是根据不同的协议定义了对代理层进行各种操作的管理接口。

二、Java JMX API

2.1 MBeans

  1. 标准 MBeans

    • MBean 接口的类名称必须以 “MBean” 为后缀,如 MBean 定义为 “XXXMBean”,那么它的实现类名必须是 “XXX”
    • MXBean 接口的类名称必须以 “MXBean” 为后缀,或者接口标记 @javax.management.MXBean 注解
  2. 动态 MBeans javax.management.DynamicMBean 接口

2.2 通知模型(Notification Model)

通知模型允许 MBean 广播管理事件,这种操作称之为通知。管理应用和其他对象注册成监听器。

EventListener(监听器) 和 EventObject(事件源) 是 JDK 自带的事件监听规范。Spring 的 ApplicationListener 也实现了这套规范,只还过 Spring 是通过 context.pulishEvent 触发事件,这里是通过 NotificationBroadcaster#sendNotification 触发的。

public void sendNotification(Notification notification) {
if (notification == null) {
return;
} boolean enabled;
for (ListenerInfo li : listenerList) {
try {
// 1. NotificationFilter 用于过滤事件类型
enabled = li.filter == null || li.filter.isNotificationEnabled(notification);
} catch (Exception e) {
continue;
}
// 2. 触发事件
if (enabled) {
executor.execute(new SendNotifJob(notification, li));
}
}
}

2.3 MBean 元数据类(MetaData Class)

元信息类包含描述所有MBean 管理接口的组件接口,其中包括:

  • 属性(Attribute) javax.management.MBeanAttributeInfo
  • 操作(Operation) javax.management.MBeanOperationInfo 和 javax.management.MBeanParameterInfo
  • 通知(Notification) javax.management.MBeanNotificationInfo
  • 构造器(Constructor) javax.management.MBeanConstructorInfo
  • javax.management.MBeanInfo

2.4 代理相关(Agent)

  • MBean 服务器:javax.management.MBeanServer
  • 管理工厂:java.lang.management.ManagementFactory

三、示例

2.1 MBean

(1) 定义接口 UserMBean

// 定义 MBean
public interface UserMBean {
// 属性
void setId(Integer id);
Integer getId(); void setName(String name);
String getName(); void setBirthDate(Date date);
Date getBirthDate(); void setTime(LocalTime time);
LocalTime getTime(); void setTest(TestBean test);
TestBean getTest(); // 操作
void printUserInfo();
Date currentDate();
} // TestBean 仅仅只是一个辅助测试的类
public class TestBean {
private String name;
private int age;
// 省略 get/set
}

(2) 定义实现类 User

public class User implements UserMBean {

    private int id;
private String name;
private Date birthDate;
private LocalTime time;
private TestBean test;
// 省略 get/set @Override
public void printUserInfo() {
System.out.printf("User: { id=%s, name=%s }\r\n", this.id, this.name);
} @Override
public Date currentDate() {
return new Date();
}
}

(3) 注册 MBean,发布服务

@Test
public void test() throws Exception {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("UserAgent:type=User1");
User user = new User();
user.setName("test");
user.setId(1);
user.setBirthDate(new Date());
user.setTime(LocalTime.now());
TestBean test = new TestBean();
test.setName("mytest");
test.setAge(11);
user.setTest(test);
mBeanServer.registerMBean(user, name); Thread.sleep(Long.MAX_VALUE);
}

此时可以通过 JDK 自带的 jconsole 或 jvisualvm 两个客户端进行连接,如下所示:

可以看到 JDK 的八种基本类型和 String 类型可以查询和修改,而 Date 和 LocalTime 只能查询不能修改,自定义的 TestBean 即不能查询也不能修改。

2.2 MXBean

MXBean 接口定义有两种实现方式,一是以 MXBean 结尾,二是使用注解。

public interface HelloMXBean {
String getName();
void setName(String name);
void setTest(TestBean test);
TestBean getTest();
} // 注解方式可以不用以 MXBean 结尾
@MXBean
public interface Hello {
String getName();
void setName(String name);
void setTest(TestBean test);
TestBean getTest();
}

实现类和注册方式和 MBean 完全相同,测试如下:

此时的 TestBean 可以正常查询。

2.3 通知

User 实现与通知相关的接口,如下:

public class User extends NotificationBroadcasterSupport implements UserMBean,
NotificationListener, NotificationFilter {
private AtomicInteger sequenceNumber = new AtomicInteger();
private String name; public User() {
addNotificationListener(this, this, null);
} // 修改属性值
@Override
public void setName(String name) {
this.name = name;
//发送通知
Notification notification = new AttributeChangeNotification(this,
sequenceNumber.incrementAndGet(), System.currentTimeMillis(),
"name changed", "name", "String",
this.name, name);
sendNotification(notification);
} // 过滤
@Override
public boolean isNotificationEnabled(Notification notification) {
if (notification instanceof AttributeChangeNotification) {
AttributeChangeNotification attrNotification = (AttributeChangeNotification) notification;
if ("name".equals(attrNotification.getAttributeName())) {
return true;
}
}
return false;
} // 执行监听方法
@Override
public void handleNotification(Notification notification, Object handback) {
printUserInfo();
} // 暴露通知信息给客户端,如 jconsole
@Override
public MBeanNotificationInfo[] getNotificationInfo() {
String[] types = new String[]{AttributeChangeNotification.ATTRIBUTE_CHANGE};
String name = AttributeChangeNotification.class.getName();
String description = "An attribute of this MBean has changed";
MBeanNotificationInfo info = new MBeanNotificationInfo(types, name,
description);
return new MBeanNotificationInfo[]{info};
} @Override
public void printUserInfo() {
System.out.println("name 的值修改为:" + this.name);
} @Override
public String getName() {
return name;
}
}

连接 jconsole 后修改 name 的属性值为 binarylei,控制台输出 name 的值修改为:binarylei

参考:

  1. 《JMX入门》:https://www.imooc.com/article/37008?block_id=tuijian_wz
  2. 《从动态日志到玩转JMX-视频》:http://www.365yg.com/a6529370724459610638/#mid=1561921308640258
  3. 《JMX通知》:http://www.tianshouzhi.com/api/tutorials/jmx/36
  4. 《JMX详解详细介绍及使用》:https://blog.csdn.net/update_java/article/details/79571237
  5. 《Spring JMX之三:通知的处理及监听》:https://www.cnblogs.com/duanxz/tag/JMX/

每天用心记录一点点。内容也许不重要,但习惯很重要!

Java JMX 监管的更多相关文章

  1. Tomcat:使用JMX监管Tomcat的几种方式

    Tomcat使用JMX管理方式,在Tomcat的自带应用manager就是使用了JMX方式来管理Tomcat,以此完成Web应用的动态部署.启动.停止. 然而manager应用是一种本地使用JMX接口 ...

  2. java jmx

    http://blog.csdn.net/qiao000_000/article/details/6063949 一.JMX简介 什么是JMX?在一篇网文中是这样说的:"JMX(Java M ...

  3. JAVA JMX协议监控

    JMX协议监控,可通过JMX协议远程监控,实时监控线上jvm情况,并通过平台管理界面进行 展示,可以通过监控实时获得线上服务器运行情况. 可以监控内存.实时线程.共享内存等各种信息. 获取实时线程信息 ...

  4. Java jmx的使用

    JMX Java Management Extensions,Java管理扩展.本质就是用来监控java语言开发的程序,一般常用于jconsole,java visual VM的监控,今天主要介绍ja ...

  5. java之JMX

    java之JMX 有关JMX的定义和架构就不具体解释了.见百度百科: http://baike.baidu.com/link? url=6QzGGEqphTmpft3ll5mXmDNVRdvLRZhk ...

  6. Java 监控基础 - 使用 JMX 监控和管理 Java 程序

    点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码网站 已经收录,有很多知识点和系列文章. 此篇文 ...

  7. 使用jmx监控tomcat

    1.在tomcat启动过程中,开启相应的参数配置: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -D ...

  8. JVM Monitoring: JMX or SNMP?

    JVM Monitoring: JMX or SNMP? By daniel on Feb 23, 2007 Since JavaTM SE 5.0, the JRE provides a means ...

  9. 在Docker中监控Java应用程序的5个方法

    译者注:Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化.通常情况下,监控的主要目的在于:减少宕机 ...

随机推荐

  1. windows的cmd下面格式化某个盘符

    1.crl+R 输入cmd回车. 2.如果要格式化的是E盘,哪直接输入 在DOS窗口中输入“format  f: “ ,其中:format 为格式化命令,f: 为需要格式化的分区

  2. python学习day3 编程语言分类 变量 格式化输出

    1.编程语言分类 机器语言:直接使用二进制指令直接编写程序,直接操作计算机硬件,必须考虑硬件细节 汇编语言:使用英文标签代替二进制指令去编写程序,直接操作计算机硬件,必须考虑硬件细节对,不过相比机器语 ...

  3. js 事件阻止冒泡

    参考 https://www.cnblogs.com/zhuzhenwei918/p/6139880.html event.stopPropagation();

  4. IDEA中配置Maven+spring MVC+tomcat

    一:配置Maven安装教程如下: http://blog.csdn.net/qq_32588349/article/details/51461182 实际安装过程中,如果按照教程配置如下属性,最后创建 ...

  5. python中matplotlib 的简单使用

    1.简单折线图的画图,轴标签.图的颜色,风格,等等参数,本文只介绍最常用的几个参数: import matplotlib.pyplot as plt import numpy as np x = np ...

  6. this.$router

    router.go(n)这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n) router.push(location)想要导航 ...

  7. 第二章 向量(a)接口与实现

  8. 安装scrapy时遇到的问题

    会报错,安装这个试试: pip install cryptography --force-reinstall 

  9. HDFS之深入简出(一)

    分布式文件系统HDFS 一:概述 1.HDFS设计目标 2.HDFS核心组件 3.HDFS副本机制 4.HDFS环境搭建 5.HDFS shell命令  java api 6.HDFS读写流程 7.H ...

  10. JS获取鼠标左(右)滑事件

    鼠标左(右)滑也是网站开发中常见的效果之一,这里对鼠标左(右)滑做出一些解释. 首先要获取需要左右滑事件的节点: eg: var div=document.getElementById("d ...