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

如何在Spring Boot 3启动后立即发布@Timed指标

解决Spring Boot 3中@Timed指标未调用不显示的问题

默认情况下,Micrometer的@Timed注解生成的指标是懒加载的,只有方法被调用一次后才会出现在/actuator/prometheus的响应中。要实现启动后直接显示初始值为0的指标,可通过以下两种方式处理:

方法一:手动预注册指定计时器

编写配置类,在应用启动完成后,手动将需要的计时器注册到MeterRegistry中,与@Timed注解的value保持一致:

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TimedMeterInitializer implements ApplicationListener<ApplicationReadyEvent> {

    private final MeterRegistry meterRegistry;

    public TimedMeterInitializer(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        // 对应@Timed(value = "get_all_books")的指标
        Timer.builder("get_all_books")
                .percentiles(0.95) // 与注解中的percentiles配置一致
                .register(meterRegistry);
    }
}

方法二:自动扫描@Timed注解并注册计时器

如果有多个带@Timed注解的方法,可通过扫描Spring管理的Bean,自动识别并注册所有对应计时器,避免手动逐个添加:

import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Method;
import java.util.Set;

@Configuration
public class AutoRegisterTimedMeters implements ApplicationListener<ApplicationReadyEvent> {

    private final MeterRegistry meterRegistry;
    private final Set<Object> springComponents;

    @Autowired
    public AutoRegisterTimedMeters(MeterRegistry meterRegistry, Set<Object> springComponents) {
        this.meterRegistry = meterRegistry;
        this.springComponents = springComponents;
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        for (Object component : springComponents) {
            Class<?> clazz = component.getClass();
            for (Method method : clazz.getDeclaredMethods()) {
                Timed timedAnnotation = AnnotationUtils.findAnnotation(method, Timed.class);
                if (timedAnnotation != null) {
                    // 优先使用注解指定的value,否则用方法名作为指标名
                    String metricName = timedAnnotation.value().isEmpty() ? method.getName() : timedAnnotation.value();
                    Timer.Builder timerBuilder = Timer.builder(metricName);

                    // 同步注解中的percentiles配置
                    if (timedAnnotation.percentiles().length > 0) {
                        timerBuilder.percentiles(timedAnnotation.percentiles());
                    }
                    // 同步注解中的描述信息(如果有)
                    if (!timedAnnotation.description().isEmpty()) {
                        timerBuilder.description(timedAnnotation.description());
                    }

                    timerBuilder.register(meterRegistry);
                }
            }
        }
    }
}

额外验证配置

确保Actuator的Prometheus端点已开启,在application.properties或application.yml中添加:

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

完成以上配置后,启动应用即可在GET /actuator/prometheus响应中看到未调用方法对应的指标(初始值为0)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:40:38