通过jmx监控jvm信息

jmx概念

JMX(Java Management Extensions,即Java管理扩展)是Java平台上为应用程序、设备、系统等植入管理功能的框架。

通过JMX,我们可以监控Java应用程序运行状态,如内存、线程等信息。常用的运维监控如jconsole,jvisualvm,Zabbix、prometheus(通过jmx_exporter采集)等工具对JVM本身的监控都是通过JMX获取的信息。

MBean

托管Bean(Managed Bean,MBean)是一种通过依赖注入创建的JavaBean。托管Bean主要用在Java管理扩展技术中。在Java EE 6的规范中,对托管Bean做了更具体的规定。

MBean代表了运行在Java虚拟机上的资源,例如应用程序或Java EE服务(事务监控、JDBC驱动程序等)。其可以用于收集如性能、资源使用率、问题信息等关键的统计信息(通过拉取),获取或设置应用程序的配置或属性(通过推送或拉取),以及对故障或状态变化等的通知事件(通过推送)。

JVM自带MBean如下:
在这里插入图片描述
除了以上这些MBean,还可以自定义MBean,此处略。

本地监控

ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
OperatingSystemMXBean osbean = ManagementFactory.getOperatingSystemMXBean();
ManagementFactory.getClassLoadingMXBean();
ManagementFactory.getMemoryMXBean();
……

远程监控

启动参数

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

注意:此处配置的端口号需与服务本身端口号不同,否则将导致服务无法正常启动。

远程访问

private GarbageCollectorMXBean youngGC;
private GarbageCollectorMXBean fullGC;
private RuntimeMXBean runtimeMXBean;
private ThreadMXBean threadMXBean;
private OperatingSystemMXBean osbean;
private ClassLoadingMXBean classLoadingMXBean;
private MemoryMXBean memoryMXBean;

#无需访问权限
JMXServiceURL serviceURL = new JMXServiceURL(url);
#JMXConnector 实现了Closeable接口,可以使用try-with-resource语法来方便关闭资源
try(JMXConnector connector = JMXConnectorFactory.connect(serviceURL )) {
	MBeanServerConnection mbs = connector.getMBeanServerConnection();
    this.runtimeMXBean = ManagementFactory.newPlatformMXBeanProxy(mbs,"java.lang:type=Runtime",
            RuntimeMXBean.class);

    this.threadMXBean = ManagementFactory.newPlatformMXBeanProxy(mbs,"java.lang:type=Threading",
            ThreadMXBean.class);

    this.osbean = ManagementFactory.newPlatformMXBeanProxy(mbs,"java.lang:type=OperatingSystem",
            OperatingSystemMXBean.class);
    this.classLoadingMXBean = ManagementFactory.newPlatformMXBeanProxy(mbs,"java.lang:type=ClassLoading",
            ClassLoadingMXBean.class);
    this.memoryMXBean = ManagementFactory.newPlatformMXBeanProxy(mbs,"java.lang:type=Memory",
            MemoryMXBean.class);
    List<GarbageCollectorMXBean> gcList = ManagementFactory.getPlatformMXBeans(mbs, GarbageCollectorMXBean.class);
    ……
    ……
}

安全性与加密访问

JMX 作为 Java的一种Bean管理机制,如果JMX服务端口暴露,那么远程攻击者可以让该服务器远程加载恶意的Bean文件(如MLet),随着Bean的滥用导致远程代码执行。
因此需要通过启用 Solr JMX 服务身份验证来保证安全性。
2019年11月18日,360CERT检测到 Solr 官方发布了安全更新,而该版本中就出现了jmx相关安全漏洞。

配置文件

如设置加密访问,需设置以下文件
密码(jmxremote.password)及权限(jmxremote.access)

#若不存在jmxremote.access文件,则复制jmxremote.password.template一份为jmxremote.password
#若存在则不执行
cp jmxremote.password.template jmxremote.password
#给密码文件加上写权限
chmod +w jmxremote.password
#给密码文件增加用户密码
echo "user password" >> jmxremote.password
#修改jmxremote.*的权限,只允许启动用户对该文件拥有读写权限:
chmod 600 jmxremote.password
以追加文件方式往jmx权限控制文件中加入一个只读权限的帐号
echo "user readonly" >> jmxremote.access

启动参数

-Dcom.sun.management.jmxremote=true  
-Djava.rmi.server.hostname=127.0.0.1
-Dcom.sun.management.jmxremote.rmi.port=10057
-Dcom.sun.management.jmxremote.local.only=false  
-Dcom.sun.management.jmxremote.port=10057  
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.password.file=${JAVA_HOME}/jre/lib/management/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=${JAVA_HOME}/jre/lib/management/jmxremote.access

远程访问

#需访问权限
JMXServiceURL serviceURL = new JMXServiceURL(url);
Map<String, Object> environment = new HashMap<>();
environment.put(JMXConnector.CREDENTIALS, new String[]{"user", "password"});
JMXConnector connector = JMXConnectorFactory.connect(serviceURL, environment);

可能的异常信息

若权限未配置出现的异常如下

2020-07-10 17:11:37 | ERROR | http-nio-10057-exec-1 | 
org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/project].
[dispatcherServlet]| 175 | Servlet.service() for servlet [dispatcherServlet] in context 
with path [/project] threw exception [Request processing failed; 
nested exception is java.lang.SecurityException: 
Authentication failed! Credentials required] with root cause
java.lang.SecurityException: Authentication failed! Credentials required
	at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticationFailure(JMXPluggableAuthenticator.java:211)
	at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticate(JMXPluggableAuthenticator.java:163)
	at sun.management.jmxremote.ConnectorBootstrap$AccessFileCheckerAuthenticator.authenticate(ConnectorBootstrap.java:227)

docker环境部署

Dockerfile

FROM openjdk:8-jre-slim
MAINTAINER user

ENV JAVA_OPTS='-Dcom.sun.management.jmxremote=true -Djava.rmi.server.hostname=ip -Dcom.sun.management.jmxremote.port=10057 -Dcom.sun.management.jmxremote.rmi.port=10057 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.password.file=/usr/local/openjdk-8/lib/management/jmxremote.password -Dcom.sun.management.jmxremote.access.file=/usr/local/openjdk-8/lib/management/jmxremote.access'
RUN cp /usr/local/openjdk-8/lib/management/jmxremote.password.template /usr/local/openjdk-8/lib/management/jmxremote.password && chmod +w /usr/local/openjdk-8/lib/management/jmxremote.password && echo "user password" >> /usr/local/openjdk-8/lib/management/jmxremote.password && chmod 600 /usr/local/openjdk-8/lib/management/jmxremote.password && echo "user readonly" >> /usr/local/openjdk-8/lib/management/jmxremote.access
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

ADD target/project-*.jar /app.jar

ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar"]
docker build -t com/project:1.0 .
docker run -d --restart=always -p 8080:880 -p 10054:10054 --name project images-docker.com.cn/common/project:0.0.1

参考文档

1、https://zh.wikipedia.org/zh-hans/JMX
2、https://www.anquanke.com/post/id/193208
3、https://stackoverflow.com/questions/970666/accessing-a-remote-garbagecollectormxbean

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值