为啥读数千分尺测量有时会返回 NaN?

Posted

技术标签:

【中文标题】为啥读数千分尺测量有时会返回 NaN?【英文标题】:Why do reading Micrometer measurement returns NaN sometimes?为什么读数千分尺测量有时会返回 NaN? 【发布时间】:2019-11-15 06:32:12 【问题描述】:

我正在尝试以编程方式读取仪表,如下所示:

获取注册表:

MeterRegistry registry = Metrics.globalRegistry.getRegistries().iterator().next();

读取测量值:

    double systemCpuUsage = registry.get("system.cpu.usage").gauge().measure().iterator().next().getValue();

问题是有时我会收到NaN

我在文档中读到了这一点:Why is my Gauge reporting NaN or disappearing?

但我不确定我该怎么做。另外,我正在阅读 Spring Boot 执行器的“内置”仪表(由 management.metrics.enable.process.cpu.usage=true 公开),所以我无法更改它的结构。

【问题讨论】:

【参考方案1】:

这是由于千分尺在仪表中使用“弱参考”。由于仪表不持有对对象的强引用,当对象被垃圾回收时,值变为NaN

如果您确实控制了仪表的创建,您可能希望自己存储一个参考,或在仪表上调用strongReference(true)

如果您遇到内置的 Spring Boot 仪表,我相信您遇到了一个错误。这很奇怪,因为创建该仪表的ProcessorMetrics 仪表绑定器拥有自己的引用(尽管它可以为空)。

当您看到NaN 时,您是否在不同的 JVM 或运行时环境中运行?

【讨论】:

基本上,我在 IDE (IntelliJ) 中运行 Spring Boot 应用程序时看到了它。和问题有关系吗? 我想知道您是否正在使用 Spring Boot 开发工具,这导致了分离。 直到现在我才意识到这一点(所以答案是“不”) 所以这个问题可能与我的本地设置有关?我在生产服务器上没有看到这个问题【参考方案2】:

在这种情况下,由于您使用的是“内置”指标,您可以覆盖 io.micrometer.core.instrument.binder.MeterBinder#bindTo,使用自定义 MeterBinder 实现重新定义 system.cpu.usage,并将 system.cpu.usage 定义为(以及您使用的其他)

Gauge.builder("system.cpu.usage", operatingSystemBean, x -> invoke(systemCpuUsage))
.strongReference(true)//Add strong reference
.tags(tags)
.description("The recent cpu usage for the whole system")
.register(registry);

请参考io.micrometer.core.instrument.binder.system.ProcessorMetrics 的例子,它现在已经定义了它。

ProcessorMetrics 上的 bean 是在 org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration 中定义的,你也需要在某个地方定义你的 bean。 (或标记@Component)

如果您不想依赖一些预定义的千分尺度量,例如捕获一些自定义列表大小,那么您可以这样做。

private static Map<String, Long> strongRefGauge = new ConcurrentHashMap<>();

要添加值,请执行以下操作

registry.gauge("CustomListSizeGuage", getMyCustomGuageTagsFor("myListName"), strongRefGauge, g -> g.get("myListName")).put("myListName", list.size());

【讨论】:

以上是关于为啥读数千分尺测量有时会返回 NaN?的主要内容,如果未能解决你的问题,请参考以下文章

千分尺 - Prometheus Gauge 显示 NaN

Arduino 上的模拟读数返回错误值

为啥 parseInt("0x") 返回 NaN [重复]

为啥 math.max() 在整数数组上返回 NaN?

matlab corr2函数为啥返回NaN值?

为啥 NaN = !NaN 返回真?