新闻详情

新闻详情

首页 / 资讯中心 / 详情

Metrics JVM Instrumentation 实战指南:基于 Dropwizard Metrics 采集 GC、内存、线程与文件描述符指标

发布时间:2026/9/27 7:38:27来源:尧图网络
Metrics JVM Instrumentation 实战指南:基于 Dropwizard Metrics 采集 GC、内存、线程与文件描述符指标
可观测性后端【免费下载链接】metrics:chart_with_upwards_trend: Capturing JVM- and application-level metrics. So you know whats going on.项目地址https://gitcode.com/gh_mirrors/met/metrics点击查看免费下载metrics-jvm是 Dropwizard Metrics当前仓库为io.dropwizard.metrics模块坐标见 metrics-jvm/pom.xml中的 JVM 集成模块它内置了一批可直接复用的Gauge与MetricSet让开发者无需编写任何 JMX 代码就能把 JVM 内部运行状态接入统一的 Metrics 体系。本文以官方手册 docs/source/manual/jvm.rst 为主线结合模块源码metrics-jvm/src/main/java/com/codahale/metrics/jvm讲解每个指标集的采集范围、指标命名、平台限制与典型接入方式帮助读者在生产环境中快速构建可观测的 JVM 监控面板。metrics-jvm 能采集哪些指标根据手册定义metrics-jvm模块覆盖五类 JVM 关键运行数据垃圾回收GC所有已发现垃圾收集器的运行次数与累计耗时内存所有内存池Memory Pool的使用情况包括堆外off-heap内存线程按线程状态NEW、RUNNABLE、BLOCKED、WAITING等的计数分解以及死锁deadlock检测文件描述符已打开文件描述符占总数的比例缓冲池Buffer Pool堆外缓冲池的大小与利用率。这些能力全部由com.codahale.metrics.jvm包下的若干MetricSet实现提供。MetricSet是 metrics-core 定义的一种分组机制它把一组相关的Metric通常是一堆Gauge打包成可整体注册的单元库作者因此可以为一大类功能提供一站式的插桩入口。手册原文指出该模块包含a number of reusable gauges and metric sets这正是其设计核心复用。快速接入一条语句注册全部 JVM 指标接入方式极其简单——只需要把各个MetricSet通过MetricRegistry.registerAll()注册到应用的 registry 即可import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.jvm.BufferPoolMetricSet; import com.codahale.metrics.jvm.ClassLoadingGaugeSet; import com.codahale.metrics.jvm.FileDescriptorRatioGauge; import com.codahale.metrics.jvm.GarbageCollectorMetricSet; import com.codahale.metrics.jvm.JvmAttributeGaugeSet; import com.codahale.metrics.jvm.MemoryUsageGaugeSet; import com.codahale.metrics.jvm.ThreadStatesGaugeSet; MetricRegistry registry new MetricRegistry(); registry.registerAll(new GarbageCollectorMetricSet()); registry.registerAll(new MemoryUsageGaugeSet()); registry.registerAll(new ThreadStatesGaugeSet()); registry.registerAll(new FileDescriptorRatioGauge()); registry.registerAll(new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer())); registry.registerAll(new ClassLoadingGaugeSet()); registry.registerAll(new JvmAttributeGaugeSet());注册之后所有指标就以标准 Metrics 形式进入 registry可被 JMX Reporter、Console、CSV、SLF4J 等报告器导出或通过 MetricsServlet 以 JSON 方式暴露。metrics-jvm的 pom.xml 显示它只依赖metrics-core与slf4j-api没有任何第三方运行库负担可以直接作为metrics-core的伴生模块引入。垃圾回收指标GarbageCollectorMetricSetGarbageCollectorMetricSet.java 为每个已发现的GarbageCollectorMXBean注册两个 gaugename.count该 GC 的运行次数对应getCollectionCount()name.time该 GC 累计耗时单位为毫秒对应getCollectionTime()。其中name取自 GC 的实际名称且源码中用WHITESPACE.matcher(gc.getName()).replaceAll(-)把名称中的空白字符替换为-。例如 HotSpot JVM 常见的 GC 名称 Copy、MarkSweepCompact、PS Scavenge、PS MarkSweep注册后会产生形如PS-Scavenge.count、PS-Scavenge.time这样的指标名。默认构造器通过ManagementFactory.getGarbageCollectorMXBeans()发现当前 JVM 的所有 GC也提供了接受CollectionGarbageCollectorMXBean的构造器便于在测试中注入 mock 对象见 GarbageCollectorMetricSetTest.java。内存指标MemoryUsageGaugeSetMemoryUsageGaugeSet.java 是内容最丰富的指标集数据来源是MemoryMXBean与全部MemoryPoolMXBean。它注册的指标分四个层级总量层total将堆与非堆相加total.init、total.used、total.max、total.committed注意源码对total.max做了特殊处理当NonHeapMemoryUsage.getMax() -1即非堆内存无上限时返回-1否则返回堆与非堆 max 之和避免出现错误的求和结果。堆层heapheap.init、heap.used、heap.max、heap.committedheap.usage一个RatioGauge比值 used / max非堆层non-heapnon-heap.init、non-heap.used、non-heap.max、non-heap.committednon-heap.usage比值 used / (max -1 ? committed : max)从源码可见当max为-1时usage会退化为以committed作为分母——这是处理 Metaspace 这类理论无上限内存区域的必要容错。内存池层pools遍历每个MemoryPoolMXBeanpools.pool.usage、pools.pool.max、pools.pool.used、pools.pool.committed、pools.pool.initpools.pool.used-after-gc仅当该池支持 GC 后使用量统计pool.getCollectionUsage() ! null时才注册例如 HotSpot 上典型的内存池指标会形如pools.PS-Eden-Space.used、pools.PS-Old-Gen.usage、pools.Code-Cache.committed、pools.Metaspace.used-after-gc。由于pools.pool覆盖了堆内存池Eden、Survivor、Old 等和堆外内存池Code Cache、Metaspace 等因此手册所说的包括 off-heap 内存正是由这一层级完整承载的。线程指标与死锁检测ThreadStatesGaugeSetThreadStatesGaugeSet.java 的数据来源是ThreadMXBean。它注册以下指标每个线程状态一个计数new.count、runnable.count、blocked.count、waiting.count、timed_waiting.count、terminated.count对应Thread.State枚举的全部值名称由state.toString().toLowerCase()生成count当前线程总数getThreadCount()daemon.count守护线程数getDaemonThreadCount()peak.count历史峰值线程数getPeakThreadCount()total_started.count累计启动线程总数getTotalStartedThreadCount()deadlock.count死锁线程数deadlocks死锁线程的诊断信息集合。在内部实现上getThreadCount(state)通过threads.getThreadInfo(threads.getAllThreadIds(), STACK_TRACE_DEPTH)一次性取回所有线程的ThreadInfoSTACK_TRACE_DEPTH 0表示不计算栈帧降低开销再逐个比对状态。从源码结构看每个状态 gauge 被读取时都会触发一次全量线程信息快照对于线程数巨大的应用这会带来可观的 CPU 开销。为此模块提供了变体 CachedThreadStatesGaugeSet.java它继承ThreadStatesGaugeSet把ThreadInfo[]缓存进一个CachedGauge在给定的时间间隔内只刷新一次// 每 5 秒缓存一次线程信息避免高频快照开销 registry.registerAll(new CachedThreadStatesGaugeSet(5, TimeUnit.SECONDS));死锁检测由独立的 ThreadDeadlockDetector.java 完成它调用ThreadMXBean.findDeadlockedThreads()找出死锁线程然后以MAX_STACK_TRACE_DEPTH 100的深度抓取每个死锁线程的栈帧输出形如线程名 locked on 锁 (owned by 持有者)的多行诊断字符串。没有死锁时返回空集合因此deadlock.count为 0、deadlocks为空是健康基线。文件描述符指标FileDescriptorRatioGaugeFileDescriptorRatioGauge.java 是一个RatioGauge返回已打开文件描述符 / 最大文件描述符的比值是排查Too many open files类故障的经典监控项。这里有一个重要的平台限制文件描述符计数依赖com.sun.management.UnixOperatingSystemMXBean。源码在静态初始化块中通过Class.forName(com.sun.management.UnixOperatingSystemMXBean)探测该类是否存在运行时若当前OperatingSystemMXBean是其实例典型 Linux/macOS JVM 满足则返回Ratio.of(getOpenFileDescriptorCount(), getMaxFileDescriptorCount())否则返回Ratio.of(NaN, NaN)。因此在非 Unix 平台或探测失败时该 gauge 会产出 NaN 而不是真实数值接入告警时需要注意这一点。对应测试见 FileDescriptorRatioGaugeTest.java。缓冲池指标BufferPoolMetricSetBufferPoolMetricSet.java 采集 JVM 的直接direct与映射mapped缓冲池指标形如direct.count、direct.used、direct.capacitymapped.count、mapped.used、mapped.capacity它直接读取java.nio:typeBufferPool,namedirect与java.nio:typeBufferPool,namemapped两个 JMX MBean 的Count、MemoryUsed、TotalCapacity属性通过模块内的 JmxAttributeGauge.java 封装成 gauge。注意它的构造器需要显式传入MBeanServer通常用ManagementFactory.getPlatformMBeanServer()。源码注释明确指出这类 JMX 对象只在 Java 7 及以上可用若 MBean 不存在如在 Java 6 上运行代码会捕获JMException并记录 debug 日志后跳过对应指标因此注册它是安全无副作用的。其他内置 MetricSet除了手册列出的五大类模块还附带两个轻量指标集ClassLoadingGaugeSet.java注册loaded累计加载类数与unloaded卸载类数两个 gauge数据来自ClassLoadingMXBean可用于观察类加载泄漏ClassLoader 无法被回收。JvmAttributeGaugeSet.java注册nameJVM 标识、vendor厂商/版本/规格拼接串、uptime进程运行毫秒数数据来自RuntimeMXBean。通常配合CpuTimeClock使用以标记主机信息与进程生命周期。另外CpuTimeClock.java 提供了基于ThreadMXBean.getCurrentThreadCpuTime()的Clock实现如果你希望 Timer 的计时基于线程 CPU 时间而非墙钟时间可以把Clock传入 registry 或 timer 构造器。指标命名与源码约定从上述源码可以总结出几条可复用的命名约定方便在监控系统中检索所有 GC、内存池名称中的空白都会被替换为-如PS Scavenge→PS-Scavenge嵌套命名使用.分隔pools.PS-Eden-Space.used、heap.usage与MetricRegistry.name()的点分风格一致属性类指标以量词收尾count、time、used、max、committed、init、capacity、uptime比例类指标用usageheap.usage、non-heap.usage、pools.pool.usage或直接以 RatioGauge 形式注册。验证与测试每个指标集在 metrics-jvm 测试目录 下都有对应测试GarbageCollectorMetricSetTest、MemoryUsageGaugeSetTest、ThreadStatesGaugeSetTest、BufferPoolMetricSetTest、ClassLoadingGaugeSetTest、FileDescriptorRatioGaugeTest、ThreadDeadlockDetectorTest等。它们大量通过 Mockito 注入 mock 的 MXBean验证getMetrics()返回的指标名与取值映射关系。阅读这些测试是理解每个指标精确语义的最快途径例如FileDescriptorRatioGaugeSunManagementNotExistsTest就专门验证了UnixOperatingSystemMXBean 不可用时返回 NaN这条平台降级路径。结合 Reporter 与 Servlet 形成完整方案metrics-jvm只负责采集输出交给metrics-core的 Reporters 与 Servlets。推荐组合用CsvReporter落盘 JVM 指标做历史分析用Slf4jReporter定期输出到日志用 MetricsServlet 把 registry 中全部 JVM 指标以 JSON 暴露给前端监控面板用 ThreadDumpServlet内部复用模块的 ThreadDump.java在排障时抓取完整线程转储。若想在生产环境通过 JMX 在线浏览这些指标可以使用 JDK 自带的jconsole或jvisualvm的 MBeans 插件查看JmxReporter暴露的 MBean——参见手册中 JMX Reporter 一节。小结metrics-jvm用极少的接入成本补齐了 JVM 观测的关键拼图GC、堆/堆外内存、线程状态与死锁、文件描述符、缓冲池全部以标准MetricSet形式与metrics-core无缝融合。使用时只需记住三点用registerAll批量注册、注意FileDescriptorRatioGauge的 Unix 平台限制与BufferPoolMetricSet的 Java 7 要求、线程数巨大的应用优先改用CachedThreadStatesGaugeSet控制采样开销。基于这些指标配合任意 reporter 即可快速构建出一套覆盖 JVM 核心运行面的监控体系。赞分享可观测性后端【免费下载链接】metrics:chart_with_upwards_trend: Capturing JVM- and application-level metrics. So you know whats going on.项目地址https://gitcode.com/gh_mirrors/met/metrics点击查看免费下载相关推荐使用 Dropwizard Metrics 采集 Caffeine 缓存指标MetricsStatsCounter 实战指南使用 Dropwizard Metrics 采集 Caffeine 缓存指标MetricsStatsCounter 实战指南 本文以 Metrics 项目的可观测性后端AMD MI350 vs NVIDIA A100Qwen3.5-397B-A17B-NVFP4跨平台推理性能对比终极指南AMD MI350 vs NVIDIA A100Qwen3.5 397B A17B NVFP4跨平台推理性能对比终极指南 在当今大模型推理领域硬件选择直接影大模型基础模型模型量化多模态本地部署go-metrics 指标采集指南基于 Prometheus 的 Docker 项目指标命名规范与实战buildkit 仓库内嵌版解析go metrics 指标采集指南基于 Prometheus 的 Docker 项目指标命名规范与实战buildkit 仓库内嵌版解析 本篇技术指南围绕当构建工具云原生后端上一篇【亲测免费】 WeUI for 小程序安装与配置指南下一篇零基础掌握Presto从安装到配置的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

isomorphic-git readTree 深度指南:直接读取 Git Tree 对象的完整实战 2026/9/27 8:24:41

isomorphic-git readTree 深度指南:直接读取 Git Tree 对象的完整实战

开发工具 【免费下载链接】isomorphic-git A pure JavaScript implementation of git for node and browsers! 项目地址: https://gitcode.com/gh_mirrors/is/isomorphic-git 点击查看 免费下载 readTree 是 isomorphic-git(纯 JavaScript 实现的 Git&a…

阅读更多 →
国庆重保安全防御部署(六):24 小时值班作战指挥链路与自动化排班 2026/9/27 8:24:41

国庆重保安全防御部署(六):24 小时值班作战指挥链路与自动化排班

国庆重保安全防御部署(六):24 小时值班作战指挥链路与自动化排班在国庆重保与重大业务活动保障期间,安全防护的核心挑战不仅在于攻防技术的对抗,更在于高强度、长周期下的应急响应组织效能。面对来自外部的持续网络扫描…

阅读更多 →
Growth 实战:用 Google Analytics 做用户数据分析——从受众群体、流量获取到移动应用 2026/9/27 8:24:41

Growth 实战:用 Google Analytics 做用户数据分析——从受众群体、流量获取到移动应用

教程 【免费下载链接】growth-ebook Growth Engineering: The Definitive Guide。全栈增长工程师指南 项目地址: https://gitcode.com/phodal/growth-ebook 点击查看 免费下载 本文是《Growth: 全栈增长工程师指南》"数据分析"篇中的实战章节。Growth 应…

阅读更多 →
在 Tekton Pipeline 项目中用好 errwrap:Go 错误包装与解包的统一模式 2026/9/27 8:24:34

在 Tekton Pipeline 项目中用好 errwrap:Go 错误包装与解包的统一模式

云原生CI/CDDevOps后端 【免费下载链接】pipeline A cloud-native Pipeline resource. 项目地址: https://gitcode.com/gh_mirrors/pipelin/pipeline 点击查看 免费下载 errwrap(github.com/hashicorp/errwrap,v1.1.0)是 HashiCo…

阅读更多 →
peco 项目源码架构解析:Package Map 包结构地图与核心 API 导读 2026/9/27 8:24:34

peco 项目源码架构解析:Package Map 包结构地图与核心 API 导读

开发工具CLI 【免费下载链接】peco Simplistic interactive filtering tool 项目地址: https://gitcode.com/gh_mirrors/pe/peco 点击查看 免费下载 peco(发音 peh-koh)是一款用 Go 编写的简易交互式过滤工具(simplistic interac…

阅读更多 →
工程师能力图谱 v2(一):AI 时代的 T 型人才核心能力雷达图 2026/9/27 8:24:34

工程师能力图谱 v2(一):AI 时代的 T 型人才核心能力雷达图

工程师能力图谱 v2(一):AI 时代的 T 型人才核心能力雷达图当 AI 辅助编码工具将基础语法实现、样板 CRUD 编写与常见算法实现的门槛降至冰点,传统依靠“熟练背诵 API、快速手写胶水代码”建立技术壁垒的研发模式正在迅速瓦解。技术…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉