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

Spring Boot 2:如何获取@Timed注解定时任务的最后一次调用Metrics指标?

解决方案

嘿,针对你的问题,我来一步步帮你搞定:

1. 先确认Actuator Metrics端点的配置是否正确

首先要确保Actuator的metrics端点已经对外暴露,在你的配置文件(比如application.properties或application.yml)里添加以下配置:

# 暴露metrics端点(按需添加,生产环境不建议用*暴露全部)
management.endpoints.web.exposure.include=metrics
# 确保metrics端点开启(默认是true,可省略)
management.endpoint.metrics.enabled=true

你已经引入了spring-boot-starter-actuator和spring-boot-starter-aop,这俩是@Timed注解生效的必要依赖,这点做的很对;而且定时方法加了open关键字(Kotlin类默认final,AOP需要代理可继承的方法),这个细节也没遗漏,很棒。

2. 获取默认的定时任务Metrics

现在访问http://xxx:yyy/actuator/metrics/importCustomers,会返回类似这样的JSON结构:

{
  "name": "importCustomers",
  "description": null,
  "baseUnit": "seconds",
  "measurements": [
    {
      "statistic": "COUNT",
      "value": 5.0
    },
    {
      "statistic": "TOTAL_TIME",
      "value": 12.345
    },
    {
      "statistic": "MAX",
      "value": 3.12
    }
  ],
  "availableTags": []
}

这里的核心字段含义:

  • COUNT:定时任务累计调用次数
  • TOTAL_TIME:所有调用的总耗时(单位取决于baseUnit,这里是秒)
  • MAX:单次调用的最大耗时

不过要注意:默认情况下,@Timed注解生成的Timer指标不会自动记录最后一次调用的时间或耗时,如果需要这个数据,得自定义Metrics来实现。

3. 添加自定义指标记录最后一次调用信息

如果你需要获取最后一次调用的时间戳或者耗时,可以通过Micrometer的Gauge来实现:

步骤一:创建类保存最后一次调用的信息

import io.micrometer.core.instrument.Gauge
import io.micrometer.core.instrument.MeterRegistry
import org.springframework.stereotype.Component
import java.time.Instant

@Component
class TaskMetrics(registry: MeterRegistry) {
    var lastInvocationTime: Instant? = null
    var lastInvocationDuration: Double? = null

    init {
        // 注册Gauge记录最后一次调用时间戳(毫秒)
        Gauge.builder("importCustomers.lastInvocationTime", this) {
            it.lastInvocationTime?.toEpochMilli()?.toDouble() ?: 0.0
        }.register(registry)
        
        // 注册Gauge记录最后一次调用耗时(单位:秒)
        Gauge.builder("importCustomers.lastInvocationDuration", this) {
            it.lastInvocationDuration ?: 0.0
        }.register(registry)
    }
}

步骤二:修改定时任务方法,更新指标数据

@Scheduled(fixedRate = 1000L * 57L)
@Timed("importCustomers")
open fun importCustomers(taskMetrics: TaskMetrics) {
    val startTime = Instant.now()
    try {
        importCustomerService.importCustomers()
    } finally {
        val durationMillis = Instant.now().toEpochMilli() - startTime.toEpochMilli()
        // 更新最后一次调用的时间和耗时
        taskMetrics.lastInvocationTime = startTime
        taskMetrics.lastInvocationDuration = durationMillis / 1000.0 // 转换为秒
    }
}

步骤三:访问自定义指标

现在你可以通过以下端点获取目标数据:

  • 最后一次调用时间戳:http://xxx:yyy/actuator/metrics/importCustomers.lastInvocationTime
  • 最后一次调用耗时:http://xxx:yyy/actuator/metrics/importCustomers.lastInvocationDuration

这样就能拿到你需要的最后一次调用的指标啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:30:54