手写!Controller接口性能监控

开发 前端
本文将介绍如何在Spring Boot应用中通过Spring Boot Actuator和Prometheus来监控任意API接口的调用耗时情况。通过Actuator提供度量metrics功能,我们能够结合AOP轻松实现API接口运行时性能指标。

1. 简介

本文将介绍如何在Spring Boot应用中通过Spring Boot Actuator和Prometheus来监控任意API接口的调用耗时情况。通过Actuator提供度量metrics功能,我们能够结合AOP轻松实现API接口运行时性能指标。结合Prometheus这一强大的监控系统,我们能够实时地查看和分析API接口的调用耗时,进而评估应用的性能状况。

2. 环境准备

2.1 依赖管理

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-prometheus</artifactId>
  <scope>runtime</scope>
</dependency>

引入Prometheus依赖包,将所有的指标数据导出为Prometheus格式。Prometheus会通过actuator接口拉取数据。同时还会注册一个/prometheus接口。

配置文件

management:
  endpoints:
    web:
      base-path: /ac
      exposure:
        include: '*'

暴露所有的端点。

3. 实战案例

本案例统计Controller接口的耗时情况,为了简单我们通过注解的方式标注需要统计的方法。

3.1 定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Monitor {
  // 作用是为不同的接口打标记
  String[] tags() default {} ;
}

其实你还可以定义比如:指标名的属性,这样可以为不同的Controller做统计。

3.2 定义切面

该切面的作用用来拦截所有使用了@Monitor注解的Controller方法,通过环绕通知进行计时处理。

@Component
@Aspect
public class MonitorAspect {
  
  private final MeterRegistry meterRegistry ;
  // 度量名称(你可以通过注解自定义)
  private static final String API_TIMER_METER_NAME = "myapp.api.timer" ; 
  
  public MonitorAspect(MeterRegistry meterRegistry) {
    this.meterRegistry = meterRegistry ;
  }
  
  @Pointcut("@annotation(monitor)")
  private void pcMonitor(Monitor monitor) {} ;
  
  @Around("pcMonitor(monitor)")
  public Object around(ProceedingJoinPoint pjp, Monitor monitor) throws Throwable {
    Timer.Sample sample = Timer.start(this.meterRegistry) ;
    String[] tags = monitor.tags() ;
    
    Object ret = null ;
    Throwable ex = null ;
    
    try {
      ret = pjp.proceed() ;
    } catch (Throwable th) {
      ex = th ;
      throw th ;
    } finally {
      List<String> listTags = new ArrayList<>() ;
      listTags.addAll(Arrays.asList(tags)) ;
      // 出现异常也会将异常名称打入tag
      if (Objects.nonNull(ex)) {
        listTags.add(ex.getClass().getSimpleName()) ;
      }
      Timer timer = meterRegistry.timer(API_TIMER_METER_NAME, listTags.toArray(new String[0])) ;
      sample.stop(timer) ;
    }  
    return ret ;
  }
}

以上切面非常的简单,统计方法执行的耗时情况。

3.3 定义接口

@Service
public class UserService {
  
  private static final List<User> DATAS = List.of(
      new User(1L, "张三", "男", 22), 
      new User(2L, "李四", "男", 23), 
      new User(3L, "王五", "女", 22), 
      new User(4L, "赵六", "男", 32)) ;


  public List<User> queryUsers() {
    sleep(2000);
    return DATAS ;
  }
  public User queryById(Long id) {
    sleep(1000);
    return DATAS.stream().filter(user -> user.getId() == id).findFirst().orElse(null) ;
  }
  
  private void sleep(int time) {
    // 模拟耗时
    try {
      TimeUnit.MILLISECONDS.sleep(new Random().nextInt(time)) ;
    } catch (InterruptedException e) {}
  }
}

Controller接口

@Monitor(tags = {"UserController", "list"})
@GetMapping("")
public List<User> list() {
  return this.userService.queryUsers() ;
}


@Monitor(tags = {"UserController", "ById"})
@GetMapping("/{id}")
public User queryById(@PathVariable Long id) {
  return this.userService.queryById(id) ;
}

注意:这里的注解属性tags必须是偶数,因为内部会通过提供的字符串tag组装成Tag对象,而Tag对象需要Key/Value。

以上是所需的所有代码,接下来进行测试。

分别访问上面的两个接口。

图片图片

图片图片

分别多次访问上面的接口,通过/ac/metrics/myapp.api.timer查看指标信息。

图片图片

通过Prometheus查看图形走势。

图片图片


通过图表方式,查看到每个接口在不同时刻的请求耗时情况。

责任编辑:武晓燕 来源: Spring全家桶实战案例源码
相关推荐

2024-07-04 11:33:33

2024-09-05 09:38:55

SpringActuator应用程序

2024-08-02 08:38:20

Controller接口地址

2017-03-02 13:31:02

监控系统

2024-06-13 08:19:08

Controller接口参数

2024-12-03 09:45:34

2024-10-05 00:00:05

高性能分布式IM

2024-09-06 07:55:42

2024-05-08 08:30:38

Controller接口组件

2022-05-23 13:44:53

前端开发优化

2015-12-11 11:49:19

java

2015-12-11 11:39:15

.net代码

2011-04-07 09:56:53

SQL Server 内存

2015-03-11 10:01:37

CDN

2021-09-13 05:00:09

监控Trends 性能

2013-02-22 09:49:29

Nagios监控性能评测

2021-09-11 21:02:24

监控Sentry Web性能

2021-01-26 08:44:48

监控工具Monasca

2023-03-01 09:07:44

前端监控异常

2019-04-08 16:50:33

前端性能监控
点赞
收藏

51CTO技术栈公众号