背景
从LifecycleMBeanBase 类分析那一篇文章中,我们已经知道
Tomcat的所有的组件都实现了JmxEnable接口,并且在初始化过程中通过Registry类注册成为Java Managed Bean 了。那么JMX在Tomcat是的运用原理是什么呢?今天就这个问题进行了实践和探究,记录一下流程。
JMX基本概念
首先,我们来看一下sun公司的官方定义
JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。
其次,至于为什么要使用JMX呢,我摘录百度过来的一篇文字的内容如下:
对于一些参数的修改,网上有一段描述还是比较形象的:
1、程序初哥一般是写死在程序中,到要改变的时候就去修改代码,然后重新编译发布。
2、程序熟手则配置在文件中(JAVA一般都是properties文件),到要改变的时候只要修改配置文件,但还是必须重启系统,以便读取配置文件里最新的值。
3、程序好手则会写一段代码,把配置值缓存起来,系统在获取的时候,先看看配置文件有没有改动,如有改动则重新从配置里读取,否则从缓存里读取。
4、程序高手则懂得物为我所用,用JMX把需要配置的属性集中在一个类中,然后写一个MBean,再进行相关配置。另外JMX还提供了一个工具页,以方便我们对参数值进行修改。
(原文链接:http://www.cnblogs.com/dongguacai/p/5900507.html)
最后,JXM的应用场景是什么呢?中间件软件WebLogic的管理页面就是基于JMX开发的,而JBoss则整个系统都基于JMX构架,而Tomcat也是支持JMX的。
通常使用JMX来监控系统的运行状态或管理系统的某些方面的功能,比如清空缓存、重新加载配置文件等。
Tomcat开启JMX
第一,tomcat默认情况下是不支持JMX的远程访问,必须手动通过启动参数来开启,仅仅支持本地的JMX访问。我本地编译的tomcat项目启动的参数如下:
-Dcatalina.home="D:\A2017Study\TomcateStudy\catalina-home" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl="false" -Dcom.sun.management.jmxremote.authenticate="false"
第二,上述配置对tomcat的启动流程有什么影响呢?通过跟踪代码,我找到在调用tomcat的Bootstrap类之前,JVM先调了Agent.startAgent方法,然后调用了ConnectorBootstrap类的startRemoteConnectorServer方法,以此来完成JMX的启动流程。
第三,startRemoteConnectorServer这个方法中,创建了JMX调用需要的MBeanServer对象,主要代码为:
MBeanServer var21 = ManagementFactory.getPlatformMBeanServer();
这行代码我们就比较熟悉了,它就创建JMX代理层的主要组件JmxMBeanServer的实例。遗憾的是,我只能通过IntelliJ的Step Out跟踪到JMX启动时调用了这两个方法,但是没找到究竟谁整合调用了这两个方法。
JMX的启动参数
在以前的Java中,要想利用JMX管理某个JVM应用,必须加上com.sun.management.jmxremote这个系统变量,以告之JVM开放特定端口和协议用于管理。但是Java6以后的版本,已经默认支持JMX了,也就是说不需要配置这个系统变量,当你启动了jconsole.exe进程访问Tomcat的时候,次数会触发Agent.startAgent方法,使其开启JMX的Connector。
而上述tomcat启动参数设置com.sun.management.jmxremote后,会在加载Pre-main类,这在sum.management的的MANIFEST.MF文件中定义了Agent的信息:
Manifest-Version: 1.0
Created-By: 1.6.0_18 (Sun Microsystems Inc.)
Agent-Class: sun.management.Agent
Premain-Class: sun.management.Agent
配置了该参数后,JVM会在启动Bootstrap类的main方法之前先调用sun.management.Agent的startAgent启动代理。而且该参数不需要指定值,空和true/false的效果都一样,都会立即启动Agent的。
没有配置该参数,JVM不会立即启动Agent,会推迟到有JMX客户端访问时才会启动Agent。即:本机的JMX始终是开启的,只是参数决定了代理启动的时机而已。如果要用jconsole监控远程主机上的Java程序,则需要修改jmx的认证配置信息,然后通过选择“远程进程”方式来监控。
查看JMBean对象
Java 提供了一个工具jconsole.exe来查看管理JMbean对象,添加JMX配置后启动本地tomcat,同时进入Java的安装bin目录下,执行jconsole.exe,打开JMX连接控制界面,选择IntelliJ启动的tomcat的Bootstrap类,如下。
进入控制界面,选择MBean页签可以看到Tomat所有管理资源如下:
这样,我们就可以通过JMX来操作tomcat,这里我能成功尝试的操作就是stop,能停掉本地的tomcat;修改connector的端口为80,刷新后重启没有成功。