Quarkus中Micrometer Gauge指标不显示或为NaN问题求助
解决Micrometer Gauge无法更新数据库指标的问题
你的问题核心是Micrometer Gauge绑定了不可变的Integer对象,导致后续值更新无法被追踪,而且每次调用方法都重复注册Gauge,这也会引发异常或指标不更新的问题。以下是具体的修复方案:
问题分析
- Integer是不可变类型,每次赋值都会生成新的实例。你在
registerMetricSalesByPaymentMode里把当前的Integer值传给registry.gauge(),Gauge只会持有这个旧实例的引用,后续metricSalesByPaymentModeEfectiu更新为新的Integer时,Gauge完全感知不到。 - 每次调用方法都注册同名同标签的Gauge,Micrometer会忽略重复注册的请求,导致新值无法生效。
修复方案
1. 使用可变数值类型替代Integer
用Micrometer提供的MutableInteger(或JDK的AtomicInteger)作为指标的存储对象,这类可变类型允许Gauge持续追踪值的变化。
2. 初始化时一次性注册Gauge
在Bean构造时完成Gauge的注册,后续只需要更新可变对象的值即可,无需重复注册。
修改后的完整代码
@ApplicationScoped public class OperationalMetricsBO { private final String METIC_NAME_PREFIX = "telecomandament.ticketing.api."; private final String METRIC_NAME_SALES_BY_PAYMENT_MODE = METIC_NAME_PREFIX+"sales.by.payment.mode"; private final MeterRegistry registry; // 用Micrometer的可变数值类型存储指标值,初始化为0 private final MutableInteger metricSalesByPaymentModeEfectiu = new MutableInteger(0); private final MutableInteger metricSalesByPaymentModeTargeta = new MutableInteger(0); public OperationalMetricsBO(MeterRegistry registry){ this.registry = registry; // 初始化时注册Gauge,绑定到可变对象 registry.gauge(METRIC_NAME_SALES_BY_PAYMENT_MODE, Tags.of("PaymentModeName", PaymentMode.EFECTIU.getName()), metricSalesByPaymentModeEfectiu); registry.gauge(METRIC_NAME_SALES_BY_PAYMENT_MODE, Tags.of("PaymentModeName", PaymentMode.TARGETA_CREDIT.getName().replace(" ", "_")), metricSalesByPaymentModeTargeta); } /** * 查询数据库并更新指标值(无需重复注册Gauge) * @return */ public List<SalesByPaymentModeDTO> updateMetricSalesByPaymentMode() { // 替换为你的数据库查询计算逻辑 int efectiuValue = CALCULATION__CODE; int targetaValue = CALCULATION__CODE; // 直接更新可变对象的值,Gauge会自动同步最新值 metricSalesByPaymentModeEfectiu.set(efectiuValue); metricSalesByPaymentModeTargeta.set(targetaValue); return salesByPaymentModeList; } }
关键说明
- MutableInteger vs AtomicInteger:两者都是线程安全的可变数值类型,
MutableInteger是Micrometer专为指标场景设计的,使用更简洁;如果想用JDK原生类,替换成AtomicInteger也是完全可行的,注册方式相同。 - 避免重复注册:重复注册同名同标签的Gauge会被Micrometer忽略,所以必须在Bean初始化时完成注册,后续只更新值。
- 方法职责优化:修改后的方法只负责更新指标值,职责更单一,也符合指标组件的设计规范。
另外,确实建议Quarkus文档补充这类从数据库动态更新指标的场景示例,帮助开发者避开这类常见的使用误区。
内容的提问来源于stack exchange,提问作者esteveavi
相关产品推荐
相关产品推荐

