1. @Timed 注解与 AOP 计时,如何实现方法级计时并控制性能开销?
如何使用 Micrometer 的 @Timed 注解结合 AOP 为方法实现计时监控,并控制由此带来的性能开销?
- @Timed 注解的配置与生效前提
- @TimedAspect 的注册方式
- 计时指标的实现原理与开销控制
@Timed 是 Micrometer 提供的注解,用于对方法执行进行计时。它本身不会自动生效,必须配合一个切面(@TimedAspect)来拦截标注了 @Timed 的方法。通常在配置类中声明一个 @Bean 返回 TimedAspect,并传入 MeterRegistry,例如 @Bean public TimedAspect timedAspect(MeterRegistry registry){ return new TimedAspect(registry); }。@Timed 支持 name、description、tags、percentiles、histogram 等属性,可指定记录百分比、直方图以及时间单位。底层实现是使用 Timer 指标,在方法执行前调用 Timer.Sample.start(),在方法正常返回或抛出异常时调用 sample.stop() 来记录耗时。性能开销主要来自切面拦截与方法调用的额外开销,通常很小(微秒级),但如果方法本身极短且调用频率极高,切面开销占比会上升,因此应避免对高频、极短的方法使用,改为手动采样或使用常量折叠友好的方式。
采用 AOP 计时能够无侵入地给业务方法加监控,但要注意 AOP 代理的开销与 Timer 注册的基数控制。控制开销的关键是限制打标的标签基数、避免对超高频方法加注解,以及使用 Timer.Sample 复用采样器。
@Configuration
public class MetricsConfig {
@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
@Service
public class OrderService {
@Timed(name = "order.create", percentiles = {0.5, 0.95, 0.99},
extraTags = {"region", "cn-north"})
public Order create(OrderDTO dto) { ... }
}