参考文档
- JMC官方用户操作指南:jmc 5.5
- JFR官方用户操作指南:jfr 5.5
- JDK Java Management Extensions
- JMX最佳实践(如何实现自己的JMX MBean)
- Java SE Monitoring and Management
- keytool官方文档
- Enabling remote JMX with password authentication and SSL
缩略语
缩写 | 全称 | 含义 |
JDK | Java Development Kit | Java开发套件 |
JDP | Java Discovery Protocol | Java发现协议 |
JFR | Java Flight Record | Java飞行记录器 |
JMC | Java Mission Control | Java任务控制 |
JMX | Java Management Extensions | Java管理扩展 |
JVM | Java Virtual Machine | Java虚拟机 |
MBean | Managed Bean(Java) | 托管Bean(Java) |
RCP | Rich Client Platform (Eclipse) | 富客户端平台(Eclipse) |
RMI | Remote Method Invocation (Java) | 远程方法调用(Java) |
JMC是什么?
Java Mission Control是由JMC客户端和一些运行在客户端上面的插件组成:
- JVM浏览器
- JMX控制台
- JFR收集器
启动JMC客户端
- windows
JAVA_HOME\bin\jmc.exe
- linux
JAVA_HOME/bin/jmc
JMC是Java应用,所以可以通过指定参数来改变应用参数。有2种方式来改变:
1.修改jmc.ini文件
文件路径跟jmc执行文件的路径一样都在JAVA_HOME\bin\jmc.exe
可见jmc.ini文件内容其实跟第2种修改启动参数的原理是一样的。
2.在jmc命令后加追加-vmargs arguments
例如:指定JVM最大最小堆均为1G
注意:如果不想覆盖jmc.ini文件里面的配置,只是做追加参数的话,就必须加上--launcher.appendVmargs
jmc.exe --launcher.appendVmargs -vmargs -Xms1G -Xmx1G
查看JVM参数是否生效
如何下载插件
从JMC的组成上就知道,插件是其重要的组成部分。
下面我们来演示,如何下载插件:
- 选择控制面板中的【帮助】
- 选择【安装新软件】
- 选择需要下载的插件即可
演示JOverflow Heap Analyzer插件的效果
如上图所示,我已经安装了JOverflow Heap Analyzer插件,这个插件看其名就知道是用于堆分析。
使用方式非常简单:
- 在【JVM浏览器】中选择想要分析的应用程序
- 右键:【Dump Heap】
- 看到效果
当然有更好的栈堆分析器,例如著名的Eclipse MAT
MX是什么?
The JMX technology was originally developed through the Java Community Process (JCP) as Java Specification Request (JSR) 3, Java Management Extensions, and JSR 160, JMX Remote API.
JMX就是一个Java标准,是用于管理和监视资源(如应用程序、设备、服务和Java虚拟机)的标准API。
JMX典型应用场景
- 查询和修改配置
- 存储应用的行为数据(CPU、GC、堆使用情况等等)
- 通知状态变化和错误情况
JMX控制台
本地连接
本地连接很简单,当你启动jmc时,它会默认扫描出当前主机上的Java应用。
例如:默认情况下,一定会包含当前JMC应用的内容,如下图所示:
连接步骤:
- 选择执行JVM
- 右键
- 选择“启动JMX控制台”即可
远程连接
使用远程连接时,一定需要保证应用的安全性。
JMX提供了2种方式:
- 基于文件的明文验证方式(存在风险)
- 通过SSL验证
生产环境上一定要同时使用明文验证和SSL验证!!!
演示远程连接
- 复制
JRE_HOME/lib/management/jmxremote.password.template
将其名字改成jmxremote.password,并为其创建dev
角色。
# 拷贝一份 cp jmxremote.password.template jmxremote.password # 修改jmxremote.password内容(如果没有权限修改先改其读写权限) chmod 777 jmxremote.password vim jmxremote.password
# 拷贝一份 cp jmxremote.password.template jmxremote.password # 修改jmxremote.password内容(如果没有权限修改先改其读写权限) chmod 777 jmxremote.password vim jmxremote.password
增加新角色dev
,其密码为admin123
保存退出后,还需将jmxremote.password文件的读写权限做限制。
# 避免出现启动JVM应用时出现Error: Password file read access must be restricted # 需要对该配置文件做读写限制 chmod 600 jmxremote.password
2.为dev角色创建读写权限
# 编辑jmxremote.access vim jmxremote.access
赋予dev
角色读写权限
3.启动Linux上的应用
有几个重要JVM需要指定:
a: com.sun.management.jmxremote
开启远程JMX
b:com.sun.management.jmxremote.port
端口号是用来启用JMX RMI连接的端口号
c:com.sun.managemt.jmxremote.authenticate
开启明文密码验证
d:com.sun.management.jmxremote.ssl
开通SSL(后续将会介绍)
java -Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.port=9964 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.managemt.jmxremote.authenticate=true \
-jar Spring-Boot-Actuator-In-Action-1.0-SNAPSHOT.jar
4.通过JMC客户端远程连接该JVM应用
a.选择"文件",点击连接
b.填写连接配置
c.点击"测试连接"
d.启动该应用的JMX控制台
启用SSL验证
开发环境下,可以只使用基于文件的明文验证。但是,生产环境上只做了明文验证是远远不够。为此,官方还提供了SSL验证的方式进行安全加固。
这里需要用到keytool
指令,这个指令是jdk自带的,无需额外下载安装。
指令路径:$JDK_HOME/bin/keytool
下面演示启用SSL验证的步骤:
注意:这里将运行在服务器上的应用简称为服务器,jmc客户端简称为客户端
1.使用keytool
在服务器端生成秘钥
# 生成服务器端的秘钥
keytool -genkeypair -v -alias 120-server -keypass admin123 -keyalg RSA -storetype PKCS12 -storepass admin123 -keystore /opt/keystores/server.jks
在/opt/keystores/
目录下将会生成名为:server.jks
2.使用keytool
导出服务器的证书
# 导出服务器端的证书
keytool -export -alias 120-server -keystore /opt/keystores/server.jks -storetype PKCS12 -keypass admin123 -file /opt/certs/120-server.cer
在/opt/certs/目录下将会生成名为:120-server.cer
3.使用keytool
在客户端生成秘钥
# 生成客户端的秘钥
keytool -genkeypair -alias client-dev-cpc -keypass admin123 -keyalg RSA -storetype PKCS12 -storepass admin123 -keystore e:/keys/pkcs12-jmx-cpc.jks
4.使用keytool
导出客户端的证书
# 导出客户端的证书 keytool -export -alias client-dev-cpc -keystore e:/keys/pkcs12-jmx-cpc.jks -storetype PKCS12 -keypass admin123 -file e:/keys/pkcs12-jmx-cpc.cer
5.使用keytool
让服务器信任客户端秘钥
想办法将客户端上的证书,上传到服务器上。FTP或者SFTP都行。
这里客户端的证书上传在:/opt/certs/
目录下
# 将客户端导入客户端已有的证书中
keytool -importcert -v -file /opt/certs/pkcs12-jmx-cpc.cer -keystore /opt/keystores/server.jks
6.使用keytool
让客户端信任服务器秘钥
想办法将服务器上的证书下载下来
# 将服务器端的证书到入到客户端已有的证书中
keytool -importcert -v -file ./120-server.cer -keystore ./pkcs12-jmx-cpc.keystore
7.启动服务器上的JVM应用程序(这里需要指定额外的JVM参数)
java -Dcom.sun.management.jmxremote=true \ -Dcom.sun.management.jmxremote.port=9964 \ -Dcom.sun.management.jmxremote.ssl=true \ -Dcom.sun.managemt.jmxremote.authenticate=true \ -Dcom.sun.management.jmxremote.registry.ssl=true \ -Djavax.net.ssl.keyStore=/opt/keystores/server.jks \ -Djavax.net.ssl.keyStorePassword=admin123 \ -Dcom.sun.management.jmxremote.ssl.need.client.auth=true \ -Djavax.net.ssl.trustStore=/opt/keystores/server.jks \ -Djavax.net.ssl.trustStorePassword=admin123 \ -jar Spring-Boot-Actuator-In-Action-1.0-SNAPSHOT.jar
8.启动客户端上的JMC客户端程序(启动JMC需要指定额外的JVM参数)
这里通过修改jmc.ini
文件
-startup
../lib/missioncontrol/plugins/org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar
--launcher.library
../lib/missioncontrol/plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.200.v20141007-2033
--launcher.appendVmargs
-vm
../jre/bin/
-vmargs
-XX:+UseG1GC
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-XX:FlightRecorderOptions=defaultrecording=true
-Djava.net.preferIPv4Stack=true
-Djavax.net.ssl.trustStore=E:\keys\pkcs12-jmx-cpc.keystore
-Djavax.net.ssl.trustStorePassword=admin123
-Djavax.net.ssl.keyStore=E:\keys\pkcs12-jmx-cpc.keystore
-Djavax.net.ssl.keyStorePassword=admin123
9.连接配置
10.测试连接
JMX开箱即用的JVM参数
官方给出如下可供配置的JVM参数,用来控制应用的JMX。
参数 | 描述 | 值 |
com.sun.management.jmxremote | 通过在JConsole和使用Attach API的任何其他本地JMX客户端使用的专用接口上发布的JMX连接器,启用JMX远程代理和本地监视。如果JConsole由与启动代理的用户相同的用户启动,则可以使用此连接器。对于通过此连接器发出的请求,不会检查密码或访问文件。 | true / false. Default is true. |
com.sun.management.jmxremote.port | 启用JMX远程代理并创建一个远程JMX连接器以侦听指定端口。默认情况下,此连接器使用SSL,密码和访问文件属性。如com.sun.management.jmxremote属性所述,它还可以启用本地监视 。 | Port number. No default. |
com.sun.management.jmxremote.registry.ssl | 将RMI连接器存根绑定到受SSL保护的RMI注册表。 | true / false. Default is false. |
com.sun.management.jmxremote.ssl | 通过SSL启用安全监视。如果为false,则不使用SSL。 | true / false. Default is true. |
com.sun.management.jmxremote.ssl.enabled.protocols | 要启用的SSL / TLS协议版本的逗号分隔列表。与com.sun.management.jmxremote.ssl结合使用 。 | Default SSL/TLS protocol version. |
com.sun.management.jmxremote.ssl.enabled.cipher.suites | 要启用的SSL / TLS密码套件的逗号分隔列表。与com.sun.management.jmxremote.ssl结合使用。 | Default SSL/TLS cipher suites. |
com.sun.management.jmxremote.ssl.need.client.auth | 如果此属性为true,并且属性 com.sun.management.jmxremote.ssl也为true,则将执行客户端身份验证。 建议将此属性设置为true。 | true / false. Default is false. |
com.sun.management.jmxremote.authenticate | 如果此属性为false,则JMX不使用密码或访问文件:所有用户都被允许全部访问。 | true / false. Default is true. |
com.sun.management.jmxremote.password.file | 指定密码文件的位置。如果 com.sun.management.jmxremote.authenticate为 false,那么将忽略此属性以及密码和访问文件。否则,密码文件必须存在且采用有效格式。如果密码文件为空或不存在,则不允许访问。 | JRE_HOME/lib/management/ jmxremote.password |
com.sun.management.jmxremote.access.file | 指定访问文件的位置。如果 com.sun.management.jmxremote.authenticate为false,则将忽略此属性以及密码和访问文件。否则,访问文件必须存在并且采用有效格式。如果访问文件为空或不存在,则不允许访问。 | JRE_HOME/lib/management/ jmxremote.access |
指定JMX代理对用户进行身份验证时使用的Java身份验证和授权服务(JAAS)登录配置条目的名称。使用此属性覆盖默认登录配置时,命名的配置条目必须位于JAAS加载的文件中。此外,配置中指定的登录模块应使用名称和密码回调来获取用户的凭据。有关更多信息,请参见javax.security.auth.callback.NameCallback和 javax.security.auth.callback.PasswordCallback的API文档 。 | Default login configuration is a file-based password authentication. |