JMX 使用指南一 Java Management Extensions

1. 什么是 JMX

JMX,全称 Java Management Extensions,是在 J2SE 5.0 版本中引入的一个功能。提供了一种在运行时动态管理资源的框架,主要用于企业应用程序中实现可配置或动态获取应用程序的状态。JMX 提供了一种简单、标准的监控和管理资源的方式,对于如何定义一个资源给出了明确的模式。

2. JMX 架构

JMX 架构分为三层:

  • 资源层:该层包含 MBean 及其可管理的资源,提供了实现 JMX 技术可管理资源的规范。
  • 代理层:或者称为 MBean Server 层,是 JMX 的核心。充当 MBean 和应用程序之间的中介。
  • 远程管理层:能够让应用程序远程通过 Connector 和 Adapter 访问 MBean Server。

在这里插入图片描述

要通过 JMX 管理资源,我们需要创建 MBean 来表示要管理的资源,然后将其注册到 MBean Server 中。MBean Server 作为所有已注册 MBean 的管理代理,实现对外提供服务以及对内管理 MBean 资源。JMX 不仅仅用于本地管理,JMX Remote API 为 JMX 添加了远程功能,使之可以通过网络远程监视和管理应用程序。我们可以使用 JMX Connector 连接到 MBean Server 并管理注册的资源。例如,可以使用 JDK 自带的 JConsole 连接到本地或远程 MBean Server。

2.1 资源探测层

资源探测层的核心是用于资源管理的 Managed bean,简称 MBean。MBean 表示在 Java 虚拟机中运行的资源,例如应用程序或 Java EE 技术服务(事务监视器、JDBC 驱动程序等)。MBean 可用来收集重点关注的统计信息,比如性能、资源使用以及问题等,也可以用于获取和设置应用程序配置或属性(推/拉模式),也还可以用于故障通知或者状态变更(推送)等。

MBean 有两种基本类型:

  • Standard MBean:这是最简单的一种 MBean。实现了一个业务接口,其中包含属性的 setter 和 getter 以及操作(即方法)。
  • Dynamic MBean:实现 javax.management.DynamicMBean 接口的 MBean,该接口提供了一种列出属性和操作以及获取和设置属性值的方法。

此外还有 Open MBeans、Model MBeans 和 Monitor MBeans。Open MBean 是依赖于基本数据类型的动态 MBean。Model MBean 是可以在运行时配置的动态 MBean。

MBean 是一个轻量级的 Java 类,它知道如何使用、获取和操作其资源,以便为代理和用户提供访问或功能。除了 JVM 会把自身的各种资源以 MBean 注册到 JMX 中,我们自己的配置、监控等资源也可以作为 MBean 注册到 JMX,这样管理程序就可以直接控制我们暴露的 MBean。为此我们需要首先创建一个接口(定义属性和操作),并且接口的名称必须以 MBean 结尾:

public interface CounterMBean {// 管理属性public int getCounter();public void setCounter(int counter);// 管理操作public void increase();public void decrease();
}

下一步是提供 MBean 接口的实现。JMX 命名约定实现类名为接口名去掉 MBean 后缀。所以我的实现类将是 Counter:

public class Counter implements CounterMBean {private int counter = 0;@Overridepublic int getCounter() {return counter;}@Overridepublic void setCounter(int counter) {this.counter = counter;}// 加1@Overridepublic void increase() {this.counter += 1;}// 减1@Overridepublic void decrease() {this.counter -= 1;}
}

MBean 允许通过使用 JMX 代理来管理资源。每个 MBean 都会暴露了底层资源的一部分属性和操作:

  • 可以读写的属性,实现包含属性的 setter 和 getter 方法,在这为 counter。
  • 可以调用的方法,可以向它提供参数或者获取返回值,在这有 increase 和 decrease。

2.2 代理层

代理层充当管理资源和应用程序之间的中介。代理层提供对来自管理应用程序的管理资源的访问。JMX 代理可以在嵌入在管理资源的机器中的 JVM 中运行,也可以位于远程位置。代理不需要知道它公开的资源以及使用公开 MBean 的管理器应用程序。它充当处理 MBean 的服务,并允许通过通过 Connector 或 Adaptor 公开的协议来操作 MBean。

代理层的职责之一是将应用程序与管理资源分离。应用程序不会直接引用管理的资源,而是通过 JMX 代理的对象名称引用调用管理操作。代理层的核心组件是 MBean Server,作为 MBean 的注册中心,并允许应用程序发现已注册 MBean 的管理接口。除此之外,代理层提供了四种代理服务,使管理 MBean 更加容易:计时器服务、监控服务、关系服务以及动态 MBean 加载服务。

想要 MBean Server 可以管理 MBean 资源,首先要把资源注册到 MBean Server 上,任何符合 JMX 的 MBean 资源都可以进行注册。现在我们需要将上面创建的 MBean 实现类 Counter 注册到 MBean Server 中:

public class CounterManagement {public static void main(String[] args) throws Exception {// 获取 MBean ServerMBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();// 创建 MBeanCounter counter = new Counter();counter.setCounter(0);// 注册ObjectName objectName = new ObjectName("com.common.example.jmx:type=Counter, name=CounterMBean");platformMBeanServer.registerMBean(counter, objectName);// 防止退出while (true) {Thread.sleep(3000);System.out.println("[INFO] 休眠 3s ..............");}}
}

首先我们通过 ManagementFactory 来获取 MBean Server 来注册 MBean。我们会使用 ObjectName 向 MbeanServer 注册 MBean 接口实现类 Counter 实例。ObjectName 由 domain:key 格式构成:

  • domain:可以是任意字符串,但根据 MBean 命名约定,一般使用 Java 包名(避免命名冲突)
  • key:以逗号分隔的’key=value’键值对列表

我们一般会定义两个 key:

  • type=MXBean 接口的实现类的类名
  • name=自定义的名字

在这里,我们使用的是:‘com.common.example.jmx:type=Counter, name=CounterMBean’。

2.3 远程管理层

远程管理层是 JMX 架构的最外层,该层负责使 JMX 代理对外部世界可用。代理层并没有实现远程访问方法,所以在远程管理层会提供一个远程通信接口对外提供服务。提供对外服务需要通过使用一个或多个 JMX Connector 或者 Adaptor 来实现。Connector 和 Adaptor 允许应用程序通过特定协议访问远程 JMX 代理,这样来自不同 JVM 的应用程序就可以调用 MBean Server 上的管理操作、获取或设置管理属性、实例化和注册新的 MBean,以及注册和接收来自管理资源的通知。

Connector 是将代理 API 暴露给其他分布式技术,例如 Java RMI,而 Adaptor 则是通过 HTTP 或者 SNMP 等不同的协议提供对 MBean 的可见性。事实上,一个代理可以使用许多不同的技术。Connector 和 Adaptor 在 JMX 环境中提供相同的功能。

JavaSE 提供了一个 Jconsole 程序,用于通过 RMI 连接到 MBean Server,这样就可以管理整个 Java 进程。下面示例我们会使用 JConsole 来演示效果。

3. 实战

我们以实际问题为例,假设我们希望给应用程序添加一个用户黑名单功能,凡是在黑名单中的用户禁止访问,传统的做法是定义一个配置文件,启动的时候读取:

# blacklist.txt
a
b
...

如果要修改黑名单怎么办?修改配置文件,然后重启应用程序。但是每次都重启应用程序实在是太麻烦了,能不能不重启应用程序?可以自己写一个定时读取配置文件的功能,检测到文件改动时自动重新读取。上述需求本质上就是在应用程序运行期间对参数、配置等进行热更新并要求尽快生效。

这个需求我们可以尝试使用 JMX 的方式实现,我们不必自己编写自动重新读取的任何代码,只需要提供一个符合 JMX 标准的 MBean 来存储用户黑名单即可。

3.1 黑名单管理接口 BlacklistMBean

JMX 的 MBean 通常以 MBean 结尾,因此我们遵循标准命名规范,首先编写一个 BlacklistMBean 接口实现对用户黑名单的管理:

public interface BlackListMBean {// 获取黑名单列表public String[] getBlackList();// 在黑名单列表中添加一个用户public void addBlackItem(String uid);// 判断某个用户是否在黑名单中public boolean contains(String uid);// 获取黑名单大小public int getBlackListSize();
}

3.2 黑名单管理实现 BlackList

MBean 有一个规则,标准 MBean 接口名称必需是在要实现类名后面加上 MBean 后缀。所以我们的黑名单管理实现类必须为 BlackList,其中定义了一个 uidSet 集合存储用户黑名单:

public class BlackList implements BlackListMBean {private Set<String> uidSet = new HashSet<>();@Overridepublic String[] getBlackList() {return uidSet.toArray(new String[0]);}@Overridepublic void addBlackItem(String uid) {uidSet.add(uid);}@Overridepublic boolean contains(String uid) {return uidSet.contains(uid);}@Overridepublic int getBlackListSize() {return uidSet.size();}
}

3.3 实时热更新黑名单 MBeanServer

下一步,我们要使用 JMX 来实时热更新这个 MBean,首先我们要把 MBean 注册到 MBeanServer 中,初始黑名单只有两个用户 a 和 b:

// 获取 MBean Server
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();// 创建 MBean 初始黑名单用户为 a 和 b
BlackList blackList = new BlackList();
blackList.addBlackItem("a");
blackList.addBlackItem("b");// 注册
ObjectName objectName = new ObjectName("com.common.example.jmx:type=BlackList, name=BlackListMBean");
platformMBeanServer.registerMBean(blackList, objectName);

下面我们使用 Socket 接收字符串模拟用户登录,并根据用户黑名单对用户进行拦截:

String hostname = "localhost";
int port = 9000;
// 循环接收
while (true) {// 简单从 Socket 接收字符串模拟接收到的用户Idtry (Socket socket = new Socket()) {socket.connect(new InetSocketAddress(hostname, port), 0);try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {char[] buffer = new char[8012];int bytes;while ((bytes = reader.read(buffer)) != -1) {String result = new String(buffer, 0, bytes);String uid = result;// 去掉换行符if (result.endsWith("\n")) {uid = result.substring(0, result.length() - 1);}if (blackList.contains(uid)) {System.out.println("[INFO] uid " + uid + " is in black list");} else {System.out.println("[INFO] uid " + uid + " is not in black list");}}}}Thread.sleep(3000);System.out.println("[INFO] 休眠 3s ..............");
}

3.4 演示

下一步就是正常启动用户登录应用程序,打开另一个命令行窗口,输入 jconsole 命令启动 JavaSE 自带的一个 JMX 客户端程序:

在这里插入图片描述

通过 jconsole 连接到我们当前正在运行的应用程序,在 jconsole 中可直接看到内存、CPU 等资源的监控。点击 MBean Tab,左侧按分类列出所有 MBean,可以在 com.common.example.jmx 下查看我们创建的 MBean 信息:

在这里插入图片描述

点击 BlackList 属性,可以看到目前黑名单中用户有 a 和 b 两个用户,即默认的黑名单用户:

在这里插入图片描述

我们在 Socket 中输入用户 a、b、c 模拟用户登录,输出日志如下:

[INFO] uid a is in black list
[INFO] uid b is in black list
[INFO] uid c is not in black list

可见,用户 a 和 b 确实被添加到了用户黑名单中了,而用户 c 不在用户黑名单中。我们点击操作 contains,填入用户 c 并点击 contains 按钮,验证用户 c 是否是在黑名单中,如下图所示用户 c 确实不在黑名单中:

在这里插入图片描述

现在我们希望用户 c 也添加在黑名单中,点击操作 addBlackItem,填入用户 c 并点击 addBlackItem 按钮。相当于 jconsole 通过 JMX 接口调用了我们自己的 BlacklistMBean 的 addBlackItem() 方法,传入的参数就是填入的用户 c:

在这里插入图片描述

再次查看属性 blackList,可以看到结果已经更新了。我们在 Socket 中输入用户 c 模拟用户登录,测试一下黑名单功能是否已生效:

[INFO] uid c is in black list

可见,用户 c 确实被添加到了黑名单中了。现在我们希望从用户黑名单中移除用户 a,点击操作 removeBlackItem 进行移除:

在这里插入图片描述

我们在 Socket 中输入用户 a 模拟用户登录测试一下黑名单功能是否生效:

[INFO] uid a is not in black list

可见,用户 a 确实从用户黑名单中移除了。


---------------------
作者:@SmartSi
来源:CSDN
原文:https://blog.csdn.net/SunnyYoona/article/details/125154198
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283640.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多种方法实现自适应布局

最近切了几个手机端的网页&#xff0c;第一次切的是美团的首页&#xff0c;为了自适应不同的手机分辨率&#xff0c;需要用到自适应布局&#xff0c;切图的时候是用的第一中方法&#xff0c;用到了定位&#xff0c;后来查找了一些其他方法&#xff0c;现在就介绍几种自适应布局…

hivesql优化的深入解析

转载&#xff1a;https://www.csdn.net/article/2015-01-13/2823530 一个Hive查询生成多个Map Reduce Job&#xff0c;一个Map Reduce Job又有Map&#xff0c;Reduce&#xff0c;Spill&#xff0c;Shuffle&#xff0c;Sort等多个阶段&#xff0c;所以针对Hive查询的优化可以大致…

如何用一行 CSS 实现 10 种现代布局

现代 CSS 布局使开发人员只需按几下键就可以编写十分有意义且强大的样式规则。上面的讨论和接下来的帖文研究了 10 种强大的 CSS 布局&#xff0c;它们实现了一些非凡的工作。 01. 超级居中&#xff1a;place-items: center 对于第一个“单行”布局&#xff0c;让我们解决所有 …

在.NET 6.0中使用不同的托管模型

本章是《定制ASP NET 6.0框架系列文章》的第六篇。在本章中&#xff0c;我们将讨论如何在ASP NET 6.0中自定义托管宿主。比如&#xff0c;托管选项和不同类型的托管&#xff0c;并了解一下IIS上的托管。限于篇幅&#xff0c;本章只是一个抛砖迎玉。本章涵盖主题包括&#xff1a…

TypeScript 与 JavaScript 的区别

TypeScript 是 JavaScript 的一个超集&#xff0c;支持 ECMAScript 6 标准&#xff08;ES6 教程&#xff09;。TypeScript 由微软开发的自由和开源的编程语言。TypeScript 设计目标是开发大型应用&#xff0c;它可以编译成纯 JavaScript&#xff0c;编译出来的 JavaScript 可以…

IO 和NIO的区别

1.IO和NIO的区别 NIO就是New IO在JDK1.4中引入。 IO和NIO有相同的作用和目的&#xff0c;但实现方式不同&#xff0c;NIO主要用到的是块&#xff0c;所以NIO的效率要比IO快不少。 在Java API中提供了两套NIO&#xff0c;一套针对标准输入输出NIO&#xff0c;另一套就是网络编程…

PerfView专题 (第四篇):如何寻找 C# 中程序集泄漏

一&#xff1a;背景 前两篇我们都聊到了非托管内存泄漏&#xff0c;一个是 HeapAlloc &#xff0c;一个是 VirtualAlloc&#xff0c;除了这两种泄漏之外还存在其他渠道的内存泄漏&#xff0c;比如程序集泄漏&#xff0c;这一篇我们就来聊一聊。二&#xff1a;程序集也会泄漏&am…

站立会议第九天

1.站立会议内容 昨天我们成功的将图片插进去了&#xff0c;在这里&#xff0c;图片是使用的png格式&#xff0c;长知识了。我们今天要继续把界面再优化一下。 照片&#xff1a; 2.任务展板 3.燃尽图 转载于:https://www.cnblogs.com/bk1246788/p/6852935.html

学习nginx 下面只是简单的配置文件

2019独角兽企业重金招聘Python工程师标准>>> #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } …

实现城市治理一网统管,必须这 4 个关键技术

导读&#xff1a;要实现城市治理一网统管&#xff0c;必须具备以下四个关键技术&#xff1a;城市状态一网感知、城市数据一网共享、信息流转三屏联动、虚实映射数字孪生。 作者&#xff1a;郑宇 来源&#xff1a;大数据DT&#xff08;ID&#xff1a;hzdashuju&#xff09; 01…

实现生成订单30分钟未支付,则自动取消

目录 了解需求 方案 1&#xff1a;数据库轮询 思路 实现 优点 缺点 方案 2&#xff1a;JDK 的延迟队列 思路 实现 优点 缺点 方案 3&#xff1a;时间轮算法 思路 实现 优点 缺点 方案 4&#xff1a;redis 缓存 思路一 实现一 解决方案 思路二 实现二 优…

CA周记-.NET MAUI in GCR 月报(2022年8月)

.NET MAUI 正式版本发布已经三个月了&#xff0c;有小伙伴希望我们有一些关于 .NET MAUI 相关的本地化内容以及开源项目介绍&#xff0c;接下来从8月开始&#xff0c;我希望用月报的形式和大家分享 .NET MAUI 在中国的活动&#xff0c;学习资源&#xff0c;优秀的开源项目&…

一文读懂研发效能洞察的五大流动指标

作者 | 张乐 目录 1 数字化时代&#xff0c;软件研发本身也要数字化 2 流框架及五大流动指标 1. 流动速率 2. 流动时间 3. 流动负载 4. 流动效率 5. 流动分布 3 研发过程中的常见瓶颈及解决思路 1. 稀缺的专家或资源&#xff0c;导致流动受阻 2. 缺乏自动化或工程能…

RabbitMQ队列

RabbitMQ是什么&#xff1f; RabbitMQ是一个在AMQP基础上完整的&#xff0c;可复用的企业消息系统。他遵循Mozilla Public License开源协议。 MQ全称为Message Queue, 消息队列&#xff08;MQ&#xff09;是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息&…

《ASP.NET Core 6框架揭秘实例》演示[14]:日志的进阶用法

为了对各种日志框架进行整合&#xff0c;微软创建了一个用来提供统一的日志编程模式的日志框架。《ASP.NET Core 6框架揭秘》实例演示[13]&#xff1a;日志的基本编程模式》以实例演示的方式介绍了日志的基本编程模式&#xff0c;现在我们来补充几种“进阶”用法。[本文节选《A…

什么是云原生,云原生技术为什么这么火?

文章目录 一、开篇浅谈二、云计算是什么三、云原生是什么四、云计算的四个层次 4.1 IaaS&#xff08;基础架构即服务&#xff09;4.2 PaaS&#xff08;平台即服务&#xff09;4.3 SaaS&#xff08;软件即服务&#xff09;4.4 DaaS&#xff08;数据即服务&#xff09;五、云原生…

PerfView专题 (第五篇):如何寻找 C# 托管内存泄漏

一&#xff1a;背景 前几篇我们聊的都是 非托管内存泄漏&#xff0c;这一篇我们再看下如何用 PerfView 来排查 托管内存泄漏 &#xff0c;其实 托管内存泄漏 比较好排查&#xff0c;尤其是用 WinDbg&#xff0c;毕竟C#是带有丰富的元数据&#xff0c;不像C下去就是二进制。二&a…

DevOps及DevOps常用的工具介绍

目录 1. 什么是 DevOps2. DevOps 概念的起源 2.1. 单体架构 瀑布模式2.2. 分布式架构 敏捷开发模式 2.2.1. 多人协同开发问题2.2.2. 多机器问题2.2.3. 开发和运维角色的天生对立问题2.3. 微服务架构 DevOps3. DevOps 到底是什么4. DevOps 常用的工具 4.1. Jenkins4.2. Kuber…

2018年SIAF 广州国际工业自动化技术及装备展览会下周隆重开幕

同期研讨活动聚焦行业未来趋势&#xff0c;探索技术发展及实际应用层面。 华南最重要的工业自动化行业盛会之一&#xff0c;SIAF广州国际工业自动化技术及装备展览会&#xff0c;将于2018年3月4至6日在广州中国进出口商品交易会展馆隆重开幕。为期三天的展会将再度与广州国际模…

相约现在,遇见未来

# 遇见未来这个世界很小&#xff0c;我们就这样遇见。这个世界很大&#xff0c;分开就很难再见。大家好&#xff0c;我是 chait&#xff0c;很高兴我们在这里《遇见》。今天是我申请公众号通过后的第一天&#xff0c;也是在该平台发表的第一篇文章&#xff0c;唠嗑点啥呢&#…