Java JVM 可观测的原理解释和落地方案对比

本文介绍了如何监控 JVM,重点对比了三种暴露 JVM 指标的开源工具:Spring Boot Actuator、JMX Exporter 和 OpenTelemetry Java Agent。通过 Prometheus 和 Grafana 实现统一监控,并探讨了它们的适用场景和优缺点。
摘要由CSDN通过智能技术生成

如何监控 JVM

我们使用 Prometheus 来作为可观测平台的指标监控的核心组件。监控一个云原生的 Java 应用,一般会分成 3 个步骤:

  1. 配置 Java 应用,暴露 JVM 指标信息

  2. 通过 Prometheus 采集并存储指标数据

  3. 通过 Grafana 的 Dashboard 展示采集到的指标

借力社区生态,我们有越来越丰富的方式来暴露 JVM 核心指标,文本将介绍 JVM 监控的基本原理,并重点介绍常见的 3 种暴露 JVM 指标的方案,可以根据读者的使用场景来选择。

采集原理

Java Management Extensions(JMX)技术是 Java SE 平台的标准功能,提供了一种简单的、标准的监控和管理资源的方式,对于如何定义一个资源给出了明确的结构和设计模式,主要用于监控和管理 Java 应用程序运行状态、设备和资源信息、Java 虚拟机运行情况等信息。并且如下图所示,有关应用程序性能和资源使用情况的详细信息可以从 JMX 指标中导出。如果有任何问题,我们可以借助收集的指标进行诊断,并对系统进行微调以获得最佳性能。JMX 是可以动态的,所以也可以在资源创建、安装、实现时进行动态监控和管理,JDK 自带的 jconsole 就是使用 JMX 技术实现的监控工具。图片:

使用 JMX 技术时,通过定义一个被称为 MBean 或 MXBean 的 Java 对象来表示要管理指定的资源,然后可以把资源信息注册到 MBean Server 对外提供服务。MBean Server 充当了对外提供服务和对内管理 MBean 资源的代理功能,如此优雅的设计让 MBean 资源管理和 MBean Server 代理完全独立开,使之可以自由的控制 MBean 资源信息。

JMX 不仅仅用于本地管理,JMX Remote API 为 JMX 添加了远程功能,使之可以通过网络远程监视和管理应用程序。得益于相对独立的架构设计,使 JMX 可以平滑的集成到各种监控系统之中。并具有包括遵守 Java 规范、通用的管理方式、开箱即用的监控功能、架构设计优秀、监测 JVM 状态能力、管理解决方案集成的能力等优点。

JMX 技术架构主要有资源管理(MBean/MXBean)模块,资源代理模块(MBean Server),远程管理模块(Remote API)组成 ,下面的图片来自维基百科,很好的展示了三个模块之间的关系。图片:

资源管理在架构中标识为资源探测层(Probe Level),在 JMX 中, 使用 MBean 或 MXBean 来表示一个资源(下面简称 MBean),访问和管理资源也都是通过 MBean。

JMX 已经对 JVM 进行了多维度资源检测,所以可以轻松启动 JMX 代理来访问内置的 JVM 资源检测,从而通过 JMX 技术远程监控和管理 JVM。JMX 内置了常用的 JVM 资源监测类,包括但不限于:类加载、垃圾收集、日志系统、内存池、内存、内存系统、操作系统、运行时系统和线程系统。

以下代码演示了如何使用原生 JMX 接口获取 JVM 指标:

package org.example.jmx;
import java.lang.management.CompilationMXBean;import java.lang.management.GarbageCollectorMXBean;import java.lang.management.ManagementFactory;import java.lang.management.MemoryMXBean;import java.lang.management.MemoryManagerMXBean;import java.lang.management.MemoryUsage;import java.lang.management.OperatingSystemMXBean;import java.util.Arrays;import java.util.List;import java.util.stream.Collectors;
public class Main {
  
    public static void main(String[] args) {
          printOSInfo();        System.out.println("================");        printMemoryManagerInfo();        System.out.println("================");        printGCInfo();    }
    //通过 OperatingSystemMXBean 获取 OS 信息    public static void printOSInfo() {
          OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();        String osName = operatingSystemMXBean.getName();        String osVersion = operatingSystemMXBean.getVersion();        int processors = operatingSystemMXBean.getAvailableProcessors();        System.out.println(String.format("OS:%s,Version:%s,CPU:%d 个", osName, osVersion, processors));
        CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();        String compilationMXBeanName = compilationMXBean.getName();        System.out.println("编译系统:" + compilationMXBeanName);
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();        long max = heapMemoryUsage.getMax();        long used = heapMemoryUsage.getUsed();        System.out.println(String.format("使用内存:%dMB/%dMB", used / 1024 / 1024, max / 1024 / 1024));
        List<GarbageCollectorMXBean> gcMXBeans = ManagementFactory.getGarbageCollectorMXBeans();        String gcNames = gcMXBeans.stream()                                  .map(MemoryManagerMXBean::getName)                                  .collect(Collectors.joining(","));        System.out.println("垃圾收集器:" + gcNames);    }
    // 通过 MemoryManagerMXBean 获取 JVM 内存管理器信息    public static void printMemoryManagerInfo() {
          List<MemoryManagerMXBean> managers = ManagementFactory.getMemoryManagerMXBeans();        if (managers != null && !managers.isEmpty()) {
              for (MemoryManagerMXBean manager : managers) {
                  System.out.println("vm内存管理器:名称=" + manager.getName() + ",管理的内存区="                                       + Arrays.deepToString(                    manager.getMemoryPoolNames()) + ",ObjectName=" + manager.getObjectName());            }        }    }
    //通过 GarbageCollectorMXBean 获取 JVM GC 信息    public static void printGCInfo() {
          try {
              List<GarbageCollectorMXBean> gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
            for (GarbageCollectorMXBean gcMxBean : gcMxBeans) {
                  System.out.println(gcMxBean.getName());                System.out.println(gcMxBean.getObjectName());            }
        } catch (RuntimeException re) {
              throw re;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值