JMX 远程JVM监控

概述

当线上服务器发生JVM相关问题的时候,能够监听内存、CPU、线程、类加载 等指标就非常重要。目前容器设计使用了arthas监控,命令行界面不太友好且容器挂了后arthas进程也挂了,因此开始调研JMX远程监控JVM方式。

参考文档

https://docs.oracle.com/cd/E19698-01/816-7609/6mdjrf86t/index.html

JMX协议

JMX(Java Management Extentions)技术提供了一系列工具,使用这些工具我们可以构建用于管理和监控设备与应用的解决方案。JMX 从 Java5 开始包含在 JDK 里发布。

JMX局限性

1、JMX 协议对NAT网络、防火墙不友好,内部通讯机制会传递内网的ip到客户端导致无法正常连接;

2、只能在问题发生后,再开启JMX远程监控,解决问题比较滞后;

3、需要配合客户端工具jconsole、JVisualVM等工具监控;

Java应用开启JMX监控

通过追加JVM-D参数开启JMX

-Djava.rmi.server.hostname=0.0.0.0
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

以上方式没有开启认证,存在安全问题,禁止在生产环境采用该方式。

service:jmx:rmi:///jndi/rmi://127.0.0.1:12345/jmxrmi

注意:JMX局限性考虑,只能在内网使用该方案监控。【适合本地使用】

开启认证-密码模式

开启密码后,默认会加载$JAVA_HOME\jre\lib\management\jmxremote.password

-Dcom.sun.management.jmxremote.authenticate=true

手动指定密码配置文件

-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=/app/jmxremote.password

JMXMP 协议

JMXMP 全称为 JMX Messaging Protocol,它的安全设施比 RMI 更加高级。请回顾下前文引用的 JMX 三层架构图,Remote Management Level 中的 RMI 是可以替换为 JMXMP 协议的。

在 JMXMP connector 里面,server 和 client 之间的通信依赖一条单独的 TCP 连接,每一条消息都是一个序列化的 Java 对象。而且,server 和 client 之间的通信分为两个流,每个流负责一个方向,这允许我们在任意时刻在这条连接上发送多个并发的请求给 server。

JMXMP开启后,TCP端口能够在公网上直接使用,但需要注意添加认证。

开发JMXMP暴露监控端口

    org.jvnet.opendmk    jmxremote_optional    1.0_01-ea

通过注册SpringBean启动JMXMP协议。

package com.panzhi.tech.common.core.jmxmp;

import com.panzhi.tech.common.core.jmxmp.config.JMXProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import javax.annotation.Resource;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.lang.management.ManagementFactory;


/**
 * JMXMP 监控
 *
 * @author marker
 */
@Slf4j
public class JMXMPService implements DisposableBean, InitializingBean {

    private JMXConnectorServer jmxConnectorServer;


    @Resource
    private JMXProperties jmxProperties; // 这里配置host:port 0.0.0.0:8001


    /**
     * afterPropertiesSet
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        if (Boolean.FALSE.equals(jmxProperties.getEnabled())) {
            return;
        }
        try {
            JMXServiceURL url = 
              new JMXServiceURL(null, jmxProperties.getHost(), jmxProperties.getPort());
            jmxConnectorServer = JMXConnectorServerFactory
                    .newJMXConnectorServer(url, null, ManagementFactory.getPlatformMBeanServer());
            // 启动监控服务
            jmxConnectorServer.start();
        } catch (IOException e) {
            log.error("JMX MP初始化失败", e);
        }
    }


    @Override
    public void destroy() throws Exception {
        if (Boolean.FALSE.equals(jmxProperties.getEnabled())) {
            return;
        }
        jmxConnectorServer.stop();
    }

}

jvisualvm链接JMXMP端口

jvisualvm命令中需要添加-cp:a加载  jmxremote_optional-1.0_01-ea.jar包或拷贝到lib/ext目录下。

  • 方式一(推荐)

将文件拷贝到 $JAVA_HOME\jre\lib\ext 目录下,启动jvisualvm.exe。

  • 方式二

D:\SDK\JDK1.8\bin> jvisualvm.exe -cp:a D:\SDK\JDK1.8\lib\jmxremote_optional-1.0_01-ea.jar

开启jvisualvm后,点击【1747809787392.png】添加JMX链接,输入链接地址,勾选不要求SSL点击【确定】

1747809744570.png

service:jmx:jmxmp://10.233.90.6:8001

JMXMP开启认证?

后期有时间再解决,待解决

通过JVM参数开启JMXMP

通过环境变量开启JMXMP,由于安全问题未解决,需要关注的时候在开启,不需要使用则关闭。

JAVA_JMX_OPTS="-Dmanagement.jmxmp.enabled=true -Dmanagement.jmxmp.host=0.0.0.0 -Dmanagement.jmxmp.port=8001"

当环境变量配置在JVM 启动参数中后,8001端口将开启,如果是容器跑的,在容器内部开启8001。需要将8001端口映射到宿主机才能够访问到JMXMP监控信息。

使用JVisualVM

JVisualVM链接上JMX的效果

1747809386078.png

监控 CPU& 内存

1747809411411.png

注意:重点禁止点击【堆dump】,它会使用这个应用卡死,并且传递这个内存的数据占用网络资源。

监控线程

1747809432149.png

这里的线程监控没有到具体类,也没有top功能,建议还是使用arthas监控thread,可以做到TOP10 的CPU消耗线程。

实时监控GC情况

1747809460221.png

需要安装visual GC 插件,需要JDK支持,镜像的openjdk不支持

来源: 雨林博客(www.yl-blog.com)