You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多服务场景下Micrometer指标在Prometheus采集端异常问题

问题分析与解决方案

核心问题定位

你遇到的现象是:/actuator/metrics/callcount能展示两个不同标签的指标实例,但/actuator/prometheus仅返回第一个,本质原因大概率是指标未被正确注册到同一个PrometheusMeterRegistry实例,或者存在多个MeterRegistry导致指标分散存储。


排查与解决步骤

1. 确认Spring上下文内MeterRegistry的唯一性

添加一个命令行运行器,打印所有存在的MeterRegistry实例及其包含的指标,验证两个callcount是否在同一个PrometheusMeterRegistry中:

@Bean
CommandLineRunner checkMeterRegistries(List<MeterRegistry> registries) {
    return args -> {
        println("检测到 ${registries.size()} 个 MeterRegistry 实例:")
        registries.each { registry ->
            println("- ${registry.getClass().simpleName} (ID: ${System.identityHashCode(registry)}),包含 ${registry.meters.size()} 个指标:")
            registry.meters.each { meter ->
                println("  - ${meter.id.name},标签: ${meter.id.tags}")
            }
        }
    }
}

运行程序并触发端点后,查看控制台输出:

  • 如果发现多个PrometheusMeterRegistry,说明存在重复配置,需移除多余的Registry定义;
  • 如果callcount{call_type='external'}不在PrometheusMeterRegistry中,说明该指标被注册到了其他Registry(比如SimpleMeterRegistry)。

2. 验证指标注册的一致性

修改MetricsUtil,添加日志确认两次指标操作使用的是同一个Registry实例,同时提前预创建Counter避免重复注册:

class MetricsUtil {

    private MeterRegistry meterRegistry
    private final Counter restControllerCounter
    private final Counter externalCounter

    @Autowired
    MetricsUtil (MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry
        println("MetricsUtil 初始化,使用 Registry ID: ${System.identityHashCode(meterRegistry)}")
        
        // 提前预创建Counter,避免重复注册
        this.restControllerCounter = Counter.builder("callcount")
            .tag("call_type", "rest_controller")
            .register(meterRegistry)
        this.externalCounter = Counter.builder("callcount")
            .tag("call_type", "external")
            .register(meterRegistry)
    }

    public void incrementRestControllerCall() {
        restControllerCounter.increment()
        println("递增rest_controller指标,Registry ID: ${System.identityHashCode(meterRegistry)}")
    }

    public void incrementExternalCall() {
        externalCounter.increment()
        println("递增external指标,Registry ID: ${System.identityHashCode(meterRegistry)}")
    }
}

触发端点后,检查控制台日志,确保两次操作的Registry ID一致。

3. 检查Spring Boot自动配置状态

在application.properties中添加debug=true,启动程序后查看自动配置报告,确认PrometheusMetricsAutoConfiguration被标记为Skipped(因为你自定义了PrometheusMeterRegistry Bean),避免自动配置的Registry与自定义Registry冲突。

4. 升级Micrometer版本尝试

当前使用的1.12.3版本存在少量已知的Registry指标同步问题,建议升级到最新稳定版(如1.13.x),修改依赖:

implementation 'io.micrometer:micrometer-core:1.13.5'
implementation 'io.micrometer:micrometer-registry-prometheus:1.13.5'

关键优化建议

不要在每次调用时动态创建Counter,提前预创建并复用,既提升性能,也避免重复注册可能带来的指标异常。

内容的提问来源于stack exchange,提问作者RektAngle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:27:54