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

如何从Spring Boot单例类中采集Prometheus的Summary指标

解决Spring Boot中@Component类里Prometheus指标无法被采集的问题

这个问题我之前也碰到过,核心原因是指标注册的上下文不对,或者说没有和Spring Boot的监控体系正确整合。下面给你两种解决方案,优先推荐第一种官方规范的方式:

方案1:使用Spring Boot官方推荐的Micrometer集成Prometheus

Spring Boot官方是通过Micrometer来对接各种监控系统(包括Prometheus)的,这种方式能完美和Spring生态整合,避免原生API的兼容性问题。

步骤1:添加依赖

首先确保你的项目里有这两个依赖(Maven示例):

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

步骤2:配置暴露Prometheus端点

在application.properties(或application.yml)里开启Actuator的Prometheus端点:

# 暴露prometheus端点
management.endpoints.web.exposure.include=prometheus
# 启用Prometheus指标导出
management.metrics.export.prometheus.enabled=true

步骤3:在@Component类中使用Micrometer的Summary

通过构造注入MeterRegistry,用Micrometer的API创建和管理指标:

@Component
public class SomeClass {

    private final Summary apiLatencySummary;
    private SimpleTimer timer;

    // 构造注入Spring管理的MeterRegistry
    public SomeClass(MeterRegistry meterRegistry) {
        this.apiLatencySummary = Summary.builder("api_latency")
                .description("elapsed time in call to api")
                .register(meterRegistry);
    }

    @Scheduled(cron = "${scheduled.job.time}")
    public void run() {
        timer = new SimpleTimer();
        // 执行你的API调用逻辑
        apiLatencySummary.record(timer.elapsedSeconds());
    }
}

这样配置后,启动项目访问/actuator/prometheus就能看到api_latency指标了,Prometheus配置好采集这个端点就能拿到数据。

方案2:使用Prometheus原生Java Client(不推荐,但可以解决)

如果你一定要用原生的Prometheus Java Client,核心是要把指标注册到Spring Boot Actuator使用的CollectorRegistry,而不是默认的全局注册表。

修改后的代码示例

@Component
public class SomeClass {

    private final Summary summary;
    private SimpleTimer timer;

    // 注入Spring提供的CollectorRegistry
    public SomeClass(CollectorRegistry collectorRegistry) {
        this.summary = Summary.build()
                .name("api_latency")
                .help("elapsed time in call to api")
                .register(collectorRegistry);
    }

    @Scheduled(cron = "${scheduled.job.time}")
    public void run() {
        timer = new SimpleTimer();
        // 执行你的API调用逻辑
        summary.observe(timer.elapsedSeconds());
    }
}

为什么之前的代码不行?

你之前用静态变量直接调用Summary.build().register()时,指标被注册到了CollectorRegistry.defaultRegistry这个全局默认注册表,但Spring Boot Actuator暴露的是自己管理的独立CollectorRegistry,两者不互通,所以Prometheus采集不到默认注册表的指标。另外静态变量的初始化时机在Spring实例化Bean之前,根本拿不到Spring管理的注册表,自然就注册错地方了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:29:29