基于Prometheus实现SpringBoot应用数据采集与业务埋点

632 阅读2分钟

前提概要:假设你已经了解了Prometheus是做什么的,以及如何基于Prometheus搭建一个指标监控体系。 本章节将讲解如何基于Prometheus对SpringBoot进行指标采集

SpringBoot监控

添加prometheus依赖:

<!-- for monitor -->  
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-actuator</artifactId>  
</dependency>

<dependency>  
    <groupId>io.micrometer</groupId>  
    <artifactId>micrometer-registry-prometheus</artifactId>  
</dependency>

使用actuator暴露prometheus端口:

# 供prometheus监控
management:
  endpoints:
    web:
      exposure:
        # 上报所有接口
        include: "*"
  metrics:
    tags:
      # 为上报数据添加applictoin的tag
      application: ${spring.application.name}
    export:
      prometheus:
        enabled: true

Pasted image 20230522174238.png Prometheus会为自动的为SpringBoot应用产生生成非常多个监控指标,在正常情况下足够我们使用了:

业务埋点

spring-boot-actuator只能够帮助我们采集技术上的指标。如果我们想对业务指标进行监控,则可以对其进行拓展,Prometheus注解和API的方式,帮助我们快速的实现统计。

基于注解实现

  1. @Gauge - 用于度量可变值的当前状态,例如内存使用量、CPU负载、线程数等。适用于度量瞬态数据。
  2. @Time - 用于记录方法的执行频率
  3. @Counted - 用于记录方法的调用次数,适合记录应用程序中重要事件的发送情况。例如用户请求的成功或失败计数
  4. @ExceptionMetered - 用于记录异常发生的次数和频率

注意: 这些注解只是将指标名称和度量值注册到Micrometer中,并没有为所监控的指标创建实际的计数器对象。因此,我们还需要显示的将指标注册到Micrometer中:

首先我们需要额外引入micrometer-core组件

<dependency>  
    <groupId>io.micrometer</groupId>  
    <artifactId>micrometer-core</artifactId>  
</dependency>

比如说我们想要监控下单接口的执行时间,则可以这样做:

@RestController
public class OrderController{

	public OrderController(MeterRegistry registry) {  
	    registry.counter("demo.order.latency");  
	}

	@PostMapping("/place")
	@Timed("demo.order.latency")
	public void place() {
		// do business code.
	}
	
}

基于API实现

除了注解,我们还可以通过API的方式处理代码块中更复杂一些的情况对其进行埋点,基本的使用方式如下:


@RestController  
public class TestController {  
  
    Counter counter;  
	// 1. 通过自动注入MeterRegistry
    public TestController(MeterRegistry registry) {  
    // 2. 通过对应的API接口构建采集器
        counter = Counter.builder("charon_test_counts")  
                .register(registry);  
    }  
  
  
    @GetMapping("/test")  
    public String get() {  
	    // 3. 执行采集任务
        counter.increment();  
        return "true";  
    }  
}

统计线程情况

通过ExecutorServiceMetrics.monitor()构造方法,我们可以对线程池进行监控以采集关键指标,以定时任务线程池为例,代码如下图所示:

@Autowired  
private MeterRegistry meterRegistry;  

private final ScheduledExecutorService EXECUTOR = ExecutorServiceMetrics.monitor(  
        meterRegistry,  
        Executors.newScheduledThreadPool(1, new ThreadFactory() {  
            @Override  
            public Thread newThread(Runnable r) {  
                Thread t = new Thread(r);  
                t.setName("schedule-thread-" + t.getId());  
                return t;  
            }  
        }), "Scheduled-Executor"  
);

结果展示

Pasted image 20230522214103.png