JMX的用处及用法

作者 : 开心源码 本文共3228个字,预计阅读时间需要9分钟 发布时间: 2022-05-12 共170人阅读

JMX最常见的场景是监控Java程序的基本信息和运行情况,任何Java程序都可以开启JMX,而后使用JConsole或者Visual VM进行预览。下图是使用Jconsle通过JMX查看Java程序的运行信息

1.png

为Java程序开启JMX很简单,只需在运行Java程序的命令后面指定如下命令就可

-Djava.rmi.server.hostname=127.0.0.1-Dcom.sun.management.jmxremote.port=1000-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false

我们从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接口

public interface ServerInfoMBean {    int getExecutedSqlCmdCount();}

在使用 Standard Mbean 作为数据传输对象的情况下这个接口的定义是必需的, 并且接口名称必需以“MBean”这个单词结尾。

二、实现具体的MBean

public class ServerInfo implements ServerInfoMBean {    public int getExecutedSqlCmdCount() {        return Dbutil.getExecutedSqlCmdCount();    }}

三、在程序的某个地方启动JMX服务并注册ServerInfoMBean

    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会自动检测到程序的进程,鼠标双击进入就可

2.png

在JConsole下面即会展现我们定义的MBean中的内容

3.png

那么如果Java程序并非运行在本地而是运行在远端服务器上我们应该如何通过用户端去连接呢, 很简单,只需使用JDK提供的JMX类库监听端口提供服务就可

                  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程序指定命令行参数也

-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

<br />而后使用JConsole的连接远端进程功能就可

4.png

其他的操作和本地无差。

这相对于提供一个http服务来完成任务是不是要简单了不少,http是一个更加笼统、应用面更广泛、功能更强大的服务,因而所作的工作也要更多少量。JMX则是一个更加具体、应用面不那么广、功能也没有http强大的服务,不过呢它胜在处理特定问题更加轻松方便,上面的示例已经很好的说明了。

此外,JMX和Jconsole并不仅仅只能展现数据,它还能执行Java方法。以上面的示例为基础我们再进行一系列改进。

一、扩展ServerInfoMBean接口和实现的类

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连接

5.png

mbean页签中出现了我们新增的方法

三、点击printString按钮调用方法

6.png

方法被调用,同时控制台也打印了通过Jconsole传递的参数

7.png

这里只是讲解了JMX的用处和最基础的使用方法,显然JMX真正提供的功能远不及此,比方它可以不用JConsole而是用户端编程的方式访问等等, 有兴趣的同学可以深入研究。

总而言之, 我觉得JMX是一种小巧精悍的工具,在不需要大张旗鼓的通过http或者者其余server\client方式提供服务时,就是他发挥用处的时机了。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » JMX的用处及用法

发表回复