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. java中excel导入\导出工具类

    1.导入工具 package com.linrain.jcs.test; import jxl.Cell; import jxl.Sheet; import jxl.Workbook; import ...

  2. java中几个happens-before规则

    1. 程序顺序规则:一个线程中的每个操作,happens-before 该线程中的任意后续操作. 2.监视器锁规则:对一个锁的解锁, happens-before 于随后对这个锁的加锁操作 3.vol ...

  3. iframe解决ajax主域和子域之间的跨域问题

    在某些应用场景下,需要在主域中,调用子域中的某个接口,如果直接在主域中向子域发ajax请求,会报跨域错误,可以用iframe来解决这种跨域问题.假如主域为www.baidu.com,子域为baike. ...

  4. 比较perl+python

    作者:iTech出处:http://itech.cnblogs.com/ http://hyperpolyglot.org/scripting   perl (1987) python (1991) ...

  5. openvpn 使用账户密码认证

    OpenVPN使用user/passwd完成验证登录 OpenVPN使用user/passwd完成验证登录1,为什么要使用user/passwd?比常规openvpn管理方便,删除用户只需要在pwd. ...

  6. ATX 安卓设备 WiFi 统一管理以及设备自动化测试

    众所周知,安卓单台设备的UI自动化测试已经比较完善了,有数不清的自动化框架或者工具.但是介绍多设备管理的内容并不多,当手里的手机多了之后,要做自动化测试平台,这块的东西又不得不碰,摆脱USB限制,接入 ...

  7. MySQL千万级数据分区存储及查询优化

    作为传统的关系型数据库,MySQL因其体积小.速度快.总体拥有成本低受到中小企业的热捧,但是对于大数据量(百万级以上)的操作显得有些力不从心,这里我结合之前开发的一个web系统来介绍一下MySQL数据 ...

  8. django的优缺点(非原创)

    Django 大包大揽,用它来快速开发一些 Web 应用是不错的.如果你顺着 Django 的设计哲学来,你会觉得 Django 很好用,越用越顺手:相反,你如果不能融入或接受 Django 的设计哲 ...

  9. Git之生成SSH公钥

    一 生成公钥 ssh-keygen -t rsa -C "michelangelo@qq.com" -t :密钥类型. -C :  注释.通常用作密钥的名字. 依次按三次回车:默认 ...

  10. Could not get lock /var/lib/dpkg/lock更新问题

    发生于apt-get update或apt update时. 常见手段,先试试: sudo rm /var/lib/dpkg/lock sudo rm /var/lib/apt/lists/lock ...