理解JMX之介绍和简单使用
从Jconsole的视图标签中见到,JConsole通过JMX展示的信息都是Java程序的通用信息,如内存情况、线程情况、类加载情况等,换言之,只要是Java程序就都具备这些信息。这些信息为我们优化程序性能、排查BUG非常有用,而JMX就是获取这些信息的基础,因此它是一种非常有用的技术。
然而JMX的强大远不止此,它出了能提供一些通用的信息以外,还能通过特定的编程接口提供一些针对具体程序的专有信息并在JConsole等JMX客户端工具中展示,具体点说就是程序员可以把需要展示的信息放在一种叫做MBean的Java对象内,然后JConsole之类的客户端工具可以连接到JMX服务,识别MBean并在图形界面中显示。从纯抽象的角度触发,这其实有点像浏览器发送一个请求给http服务器,然后http服务器执行浏览器的请求并返回相应的数据,从某种角度来说JConsole和JMX也是以这种方式工作的,只是它们使用的协议不是http,交换数据协议格式不是http数据包,但是他们的确是以客户端/服务器这种模式工作的,而且完成的事情也差不多。
那么既然有了http,JMX又有何存在意义呢。 事实上,JMX能完成的任务通过http的确都能完成,只不过某些情况下用JMX来做会更加方便。
比如说你需要知道服务器上个运行中程序的相关信息, 如执行了多少次数据库操作、任务队列中有多少个任务在等待处理
最常用的解决方案,我们会在程序中启动一个http服务,当接收到来自客户端的请求这些信息的请求时,我们的http处理程序会获得这些信息,并转换成特定格式的数据如JSON返回给客户端,客户端会以某种方式展现这些信息。
如以JMX作为解决方案,核心流程也是如此,但在数据的交换方式上会略有不同。
下面我们展示JMX是如何完成此任务的。
一、定义一个展示所需信息的MBean接口
1 2 3 | public interface ServerInfoMBean { int getExecutedSqlCmdCount(); } |
在使用 Standard Mbean 作为数据传输对象的情况下这个接口的定义是必须的, 并且接口名称必须以“MBean”这个单词结尾。
二、实现具体的MBean
1 2 3 4 5 | public class ServerInfo implements ServerInfoMBean { public int getExecutedSqlCmdCount() { return Dbutil.getExecutedSqlCmdCount(); } } |
三、在程序的某个地方启动JMX服务并注册ServerInfoMBean
1 2 3 4 5 | public static void main(String[] args) throws JMException, Exception{ MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName( "serverInfoMBean:name=serverInfo" ); server.registerMBean( new ServerInfo(), name); } |
四、运行程序,并通过JConsole查看
如果程序运行在本地,Jconsole会自动检测到程序的进程,鼠标双击进入即可
在JConsole下面即会展示我们定义的MBean中的内容
那么假如Java程序并非运行在本地而是运行在远端服务器上我们应该如何通过客户端去连接呢, 很简单,只要使用JDK提供的JMX类库监听端口提供服务即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class Main { public static void main(String[] args) throws JMException, Exception{ MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName( "serverInfoMBean:name=serverInfo" ); server.registerMBean( new ServerInfo(), name); LocateRegistry.createRegistry(8081); JMXServiceURL url = new JMXServiceURL ( "service:jmx:rmi:///jndi/rmi://localhost:8081/jmxrmi" ); JMXConnectorServer jcs = JMXConnectorServerFactory.newJMXConnectorServer(url, null , server); jcs.start(); } } |
或者在启动Java程序指定命令行参数也
1 2 3 4 | -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl= false -Dcom.sun.management.jmxremote.authenticate= false |
然后使用JConsole的连接远端进程功能即可
其余的操作和本地无差。
这相对于提供一个http服务来完成任务是不是要简单了不少,http是一个更加抽象、应用面更广泛、功能更强大的服务,因此所作的工作也要更多一些。JMX则是一个更加具体、应用面不那么广、功能也没有http强大的服务,不过呢它胜在解决特定问题更加轻松方便,上面的示例已经很好的说明了。
此外,JMX和Jconsole并不仅仅只能展示数据,它还能执行Java方法。以上面的示例为基础我们再进行一系列改进。
一、扩展ServerInfoMBean接口和实现的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public interface ServerInfoMBean { int getExecutedSqlCmdCount(); void printString(String fromJConsole); } public class ServerInfo implements ServerInfoMBean { public int getExecutedSqlCmdCount() { return 100; } public void printString(String fromJConsole) { System. out .println(fromJConsole); } } |
二、运行程序并使用JConsole连接
mbean页签中出现了我们新添加的方法
三、点击printString按钮调用方法
方法被调用,同时控制台也打印了通过Jconsole传递的参数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了