Java JMX 监管
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
标准 MBeans
MBean接口的类名称必须以 “MBean” 为后缀,如 MBean 定义为 “XXXMBean”,那么它的实现类名必须是 “XXX”MXBean接口的类名称必须以 “MXBean” 为后缀,或者接口标记 @javax.management.MXBean 注解
动态 MBeansjavax.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。
参考:
- 《JMX入门》:https://www.imooc.com/article/37008?block_id=tuijian_wz
- 《从动态日志到玩转JMX-视频》:http://www.365yg.com/a6529370724459610638/#mid=1561921308640258
- 《JMX通知》:http://www.tianshouzhi.com/api/tutorials/jmx/36
- 《JMX详解详细介绍及使用》:https://blog.csdn.net/update_java/article/details/79571237
- 《Spring JMX之三:通知的处理及监听》:https://www.cnblogs.com/duanxz/tag/JMX/
每天用心记录一点点。内容也许不重要,但习惯很重要!
Java JMX 监管的更多相关文章
- Tomcat:使用JMX监管Tomcat的几种方式
Tomcat使用JMX管理方式,在Tomcat的自带应用manager就是使用了JMX方式来管理Tomcat,以此完成Web应用的动态部署.启动.停止. 然而manager应用是一种本地使用JMX接口 ...
- java jmx
http://blog.csdn.net/qiao000_000/article/details/6063949 一.JMX简介 什么是JMX?在一篇网文中是这样说的:"JMX(Java M ...
- JAVA JMX协议监控
JMX协议监控,可通过JMX协议远程监控,实时监控线上jvm情况,并通过平台管理界面进行 展示,可以通过监控实时获得线上服务器运行情况. 可以监控内存.实时线程.共享内存等各种信息. 获取实时线程信息 ...
- Java jmx的使用
JMX Java Management Extensions,Java管理扩展.本质就是用来监控java语言开发的程序,一般常用于jconsole,java visual VM的监控,今天主要介绍ja ...
- java之JMX
java之JMX 有关JMX的定义和架构就不具体解释了.见百度百科: http://baike.baidu.com/link? url=6QzGGEqphTmpft3ll5mXmDNVRdvLRZhk ...
- Java 监控基础 - 使用 JMX 监控和管理 Java 程序
点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码网站 已经收录,有很多知识点和系列文章. 此篇文 ...
- 使用jmx监控tomcat
1.在tomcat启动过程中,开启相应的参数配置: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -D ...
- 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 ...
- 在Docker中监控Java应用程序的5个方法
译者注:Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化.通常情况下,监控的主要目的在于:减少宕机 ...
随机推荐
- 1.3.2、CDH 搭建Hadoop在安装之前(端口---Cloudera Navigator加密使用的端口)
列出的所有端口都是TCP. 在下表中,每个端口的“ 访问要求”列通常是“内部”或“外部”.在此上下文中,“内部”表示端口仅用于组件之间的通信; “外部”表示该端口可用于内部或外部通信. 零件 服务 港 ...
- cdnbest如何配置ssl证书
cdnbest添加ssl证书有三种方式: 一.第一种在站点设置中添加: 点打开,加入证书后点提交 可以点检测功能检查证书是否有效,打勾说明证书是有效的 二. 第二种是在域名记录里添加: 如下图点击,添 ...
- CRM某些表加入审计
--更新参数文件,设置Audit等级 alter system set audit_trail=db,extended scope=spfile; --更新参数文件,开始Audit alter sys ...
- mysql 连表查询
现有tablea: tableb: ...
- Linq to sql 之 ExecuteQuery 错误:指定的转换无效
问题:通过dbContext.ExecuteQuery 得到数据并赋值给一个集合. 代码: public IEnumerable<LeaveCodeSum> GetLeavTotal(st ...
- javascript学习笔记(四):DOM操作HTML
当网页被加载时,浏览器会创建页面的文档对象模型Document Object Model,简称DOM Dom操作html 1:改变页面中所有HTML元素 2:改变页面中所有HTML属性 3:改变页面中 ...
- Python基础之列表及元组的增删改查
定义一个列表 晚上的状态不太适合写博客,容易犯困~ 列表的增加有三种方式 第一种主流的增加 append函数 list1 = ['noevil', 'fordearme', 'city', 'cust ...
- helm 更改为国内源
helm init --upgrade -i slpcat/tiller:v2.8.2 --stable-repo-url https://kubernetes.oss-cn-hangzhou.al ...
- PL/SQL Dev连接Oracle弹出空白提示框的解决方法分享
第一次安装Oracle,装在虚拟机中,用PL/SQL Dev连接远程数据库的时候老是弹出空白提示框,网上找了很久,解决方法也很多,可是就是没法解决我这种情况的. 出现这种问题,解决方法大概有这几种: ...
- c# double 类型保留几位小数
C 或 c :货币 D 或 d:十进制数 E 或 e:科学记数法(指数) F 或 f:定点 G 或 g:常规 N 或 n:数字 P 或 p:百分比 double.ToString("Nx & ...