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. redis 配置参数

    redis配置参数说明: 属性 说明 daemonize 如果值是“yes”,则启动服务的时候是后台守护进程形式,如果值是“no”,则相反 pidfile 指定存储Redis进程号的文件路径 port ...

  2. Physical (Raw) Versus Logical Backups

    [Physical (Raw) Versus Logical Backups] Physical backups consist of raw copies of the directories an ...

  3. EasyUI值的清空与获取

    清空: 一般值 $("#searchx").val(""); 时间选择框 $('#starttime').datetimebox('setValue', '') ...

  4. JSF web.xml的各类参数属性配置

    出处:http://www.cnblogs.com/zxpgo/articles/2570175.html 感谢作者的分享!! ———————————————————————————————————— ...

  5. 六 json&pickle模块

    之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了 ...

  6. 全国高校绿色计算大赛 预赛第一阶段(C++)第2关:扔桃子

    挑战任务 动物园有一只小猴子喜欢吃桃子,不过它有个很独特的习惯,每次都把找到的桃子分成相等的两份,吃掉一份,留一份.如果不能等分,小猴子就会丢掉一个然后再分.第二天再继续这个过程,直到最后剩一个桃子了 ...

  7. 第十章 优先级队列 (xa3)左式堆:插入与删除

  8. numpy.random.uniform()

    numpy.random.uniform均匀分布 2018年06月19日 23:28:03 徐小妹 阅读数:4238   numpy.random.uniform介绍: 1. 函数原型:  numpy ...

  9. UmBasketella

    UmBasketella http://poj.org/problem?id=3737 Time Limit: 1000MS   Memory Limit: 65536K Total Submissi ...

  10. Quartz代码及配置详解(转)

    Quartz可以用来做什么? Quartz是一个任务调度框架.比如你遇到这样的问题 想每月25号,信用卡自动还款 想每年4月1日自己给当年暗恋女神发一封匿名贺卡 想每隔1小时,备份一下自己的爱情动作片 ...