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

如何通过Micrometer/Prometheus获取已记录的方法执行时间指标

可行方案实现指南

前提注意

Spring AOP默认无法拦截private方法,你当前标记@Timed的process方法如果是private的,注解实际不会生效。建议将方法改为public,或者启用AspectJ编织(需额外引入AspectJ依赖并在启动类添加@EnableAspectJAutoProxy(proxyTargetClass = true))。

步骤1:配置执行阈值

在application.properties或application.yml中添加阈值配置:

# 单位:毫秒,可根据需求调整
data.processing.time-threshold=500

方案一:实时监控单次执行耗时并对比阈值

该方案会在每次process方法执行后,计算实际耗时并与阈值对比,将"超过阈值的次数"作为新指标上报Prometheus。

1.1 实现监控组件

@Component
public class ProcessingTimeMonitor {
    private final long timeThresholdMs;
    private final Counter thresholdExceededCounter;

    public ProcessingTimeMonitor(MeterRegistry meterRegistry,
                                 @Value("${data.processing.time-threshold}") long timeThresholdMs) {
        this.timeThresholdMs = timeThresholdMs;
        // 注册自定义计数器,记录超过阈值的次数
        this.thresholdExceededCounter = meterRegistry.counter("data.processing.time.threshold.exceeded");
    }

    public long getTimeThresholdMs() {
        return timeThresholdMs;
    }

    public void recordThresholdExceed() {
        thresholdExceededCounter.increment();
    }
}

1.2 自定义切面拦截方法

@Aspect
@Component
public class ProcessingTimeAspect {
    private final ProcessingTimeMonitor monitor;

    public ProcessingTimeAspect(ProcessingTimeMonitor monitor) {
        this.monitor = monitor;
    }

    // 替换为你的process方法所在类的全路径
    @Around("execution(* com.yourpackage.YourClass.process(..))")
    public Object trackProcessingTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        try {
            return joinPoint.proceed();
        } finally {
            long elapsedTime = System.currentTimeMillis() - startTime;
            // 对比阈值,超过则计数
            if (elapsedTime > monitor.getTimeThresholdMs()) {
                monitor.recordThresholdExceed();
            }
        }
    }
}

方案二:定时检查统计指标与阈值对比

如果你关注的是方法执行时间的统计值(如平均值、最大值),可以定时从MeterRegistry中读取@Timed生成的Timer指标,与阈值对比后上报状态指标。

2.1 实现定时检查组件

@Component
public class TimedMetricChecker {
    private final MeterRegistry meterRegistry;
    private final long timeThresholdMs;
    private final Gauge thresholdExceededGauge;

    public TimedMetricChecker(MeterRegistry meterRegistry,
                              @Value("${data.processing.time-threshold}") long timeThresholdMs) {
        this.meterRegistry = meterRegistry;
        this.timeThresholdMs = timeThresholdMs;
        // 注册Gauge指标,1表示超过阈值,0表示未超过
        this.thresholdExceededGauge = Gauge.builder("data.processing.time.threshold.exceeded.gauge", () -> 0.0)
                .register(meterRegistry);
    }

    // 每分钟执行一次检查,可调整频率
    @Scheduled(fixedRate = 60000)
    public void checkThresholdAgainstStats() {
        // 从注册表中获取@Timed生成的Timer指标
        Timer timer = meterRegistry.find("data.processing.time").timer();
        if (timer == null) {
            return;
        }

        // 读取统计的平均耗时(单位:毫秒),也可改用max()获取最大值
        double avgTimeMs = timer.mean(TimeUnit.MILLISECONDS);
        // 更新Gauge状态
        thresholdExceededGauge.set(avgTimeMs > timeThresholdMs ? 1.0 : 0.0);
    }
}

最后配置验证

确保Actuator的Prometheus端点已开启,在配置文件中添加:

management.endpoints.web.exposure.include=prometheus
management.metrics.export.prometheus.enabled=true

启动应用后,访问/actuator/prometheus即可看到自定义的阈值相关指标,Prometheus可正常抓取这些数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:43:20