大家好!我是"无敌码农",今天要和大家分享的是在实际工作中“如何优雅地自定义Prometheus监控指标”!目前大部分使用Spring Boot构建微服务体系的公司,大都在使用Prometheus来构建微服务的度量指标(Metrics)类监控系统。而一般做法是通过在微服务应用中集成Prometheus指标采集SDK,从而使得Spring Boot暴露相关Metrics采集端点来实现。
但一般来说,Spring Boot默认暴露的Metrics数量及类型是有限的,如果想要建立针对微服务应用更丰富的监控维度(例如TP90/TP99分位值指标之类),那么还需要我们在Spring Boot默认已经打开的Metrics基础之上,配置Prometheus类库(micrometer-registry-prometheus)所提供的其他指标类型。
但怎么样才能在Spring Boot框架中以更优雅地方式实现呢?难道需要在业务代码中编写各种自定义监控指标代码的暴露逻辑吗?接下来的内容我们将通过@注解+AOP的方式来演示如何以更加优雅的方式来实现Prometheus监控指标的自定义!
自定义监控指标配置注解
需要说明的是在Spring Boot应用中,对程序运行信息的收集(如指标、日志),比较常用的方法是通过Spring的AOP代理拦截来实现,但这种拦截程序运行过程的逻辑多少会损耗点系统性能,因此在自定义Prometheus监控指标的过程中,可以将是否上报指标的选择权交给开发人员,而从易用性角度来说,可以通过注解的方式实现。例如:
package com.wudimanong.monitor.metrics.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Tp {
String description() default "";
}
如上所示代码,我们定义了一个用于标注上报计时器指标类型的注解,如果想统计接口的想TP90、TP99这样的分位值指标,那么就可以通过该注解标注。除此之外,还可以定义上报其他指标类型的注解,例如:
package com.wudimanong.monitor.metrics.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Count {
String description() default "";
}
如上所示,我们定义了一个用于上报计数器类型指标的注解!如果要统计接口的平均响应时间、接口的请求量之类的指标,那么可以通过该注解标注!
而如果觉得分别定义不同指标类型的注解比较麻烦,对于某些接口上述各种指标类型都希望上报到Prometheus,那么也可以定义一个通用注解,用于同时上报多个指标类型,例如:
package com.wudimanong.monitor.metrics.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Monitor {
String description() default "";
}
总之,无论是分开定义特定指标注解还是定义一个通用的指标注解,其目标都是希望以更灵活的方式来扩展Spring Boot微服务应用的监控指标类型。
自定义监控指标注解AOP代理逻辑实现
上面我们灵活定义了上报不同指标类型的注解,而上述注解的具体实现逻辑,可以通过定义一个通用的AOP代理类来实现,具体实现代码如下:
package com.wudimanong.monitor.metrics.aop;
import com.wudimanong.monitor.metrics.Metrics;
import com.wudimanong.monitor.metrics.annotation.Count;
import com.wudim