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

如何用Micrometer测量控制器调用异步方法的完整请求耗时

解决方案

要实现从请求进入控制器到异步服务方法执行完成的完整耗时统计,核心问题是原有控制器方法会在调用异步方法后直接返回,无法捕获异步方法的执行时间。可以通过以下步骤调整代码,结合Micrometer实现完整计时:

1. 修改异步服务方法,返回可跟踪的异步结果

将executeAsync方法的返回类型改为CompletableFuture<Void>(或Future<Void>),这样控制器可以跟踪异步任务的完成状态:

@Service
public class SomeService {

    @Async
    public CompletableFuture<Void> executeAsync() throws InterruptedException {
        Thread.sleep(2000);
        System.out.println("Async execution done!");
        return CompletableFuture.completedFuture(null);
    }
}

2. 在控制器中等待异步任务完成

修改控制器方法,调用异步方法后通过join()(或get())等待任务执行完毕,确保控制器方法的生命周期覆盖异步方法的整个执行过程:

@RestController
public class HelloController {

    @Autowired
    private SomeService someService;

    @GetMapping("/async")
    @Timed(value = "async.full.time", description = "总耗时:从请求进入到异步方法执行完成")
    public void async() throws InterruptedException {
        Thread.sleep(2000);

        // 等待异步任务完成,确保计时包含异步方法耗时
        someService.executeAsync().join();
    }
}

3. (可选)手动计时实现更灵活的控制

如果不想依赖@Timed注解,也可以用Micrometer的Timer手动统计耗时,适合需要自定义标签或逻辑的场景:

@RestController
public class HelloController {

    @Autowired
    private SomeService someService;

    @Autowired
    private MeterRegistry meterRegistry;

    @GetMapping("/async")
    public void async() throws InterruptedException {
        // 启动计时采样
        Timer.Sample sample = Timer.start(meterRegistry);
        try {
            Thread.sleep(2000);
            someService.executeAsync().join();
        } finally {
            // 停止计时并注册指标
            sample.stop(Timer.builder("async.full.time")
                    .description("总耗时:从请求进入到异步方法执行完成")
                    .register(meterRegistry));
        }
    }
}

关键说明

  • 原代码中控制器的@Timed只能统计到调用executeAsync的时间点,因为@Async方法在独立线程执行,控制器方法会立即返回。
  • 通过返回CompletableFuture并等待任务完成,让控制器方法的执行周期覆盖异步方法的整个过程,此时@Timed或手动计时就能统计完整耗时。
  • 确保项目已正确配置@EnableAsync,否则@Async注解不会生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:33:25