SpringBoot 使用Prometheus采集自定义指标数据的方案

目录
  • 一、我们需要什么指标
  • 二、在SrpingBoot中引入prometheus
  • 三、高级指标之分位数

我们在k8s集群成功搭建了Prometheus服务。今天,我们将在springboot2.x中使用prometheus记录指标。

一、我们需要什么指标

对于DDD、TDD等,大家比较熟悉了,但是对于MDD可能就比较陌生了。MDD是Metrics-Driven Development的缩写,主张开发过程由指标驱动,通过实用指标来驱动快速、精确和细粒度的软件迭代。MDD可使所有可以测量的东西都得到量化和优化,进而为整个开发过程带来可见性,帮助相关人员快速、准确地作出决策,并在发生错误时立即发现问题并修复。依照MDD的理念,在需求阶段就应该考虑关键指标,在应用上线后通过指标了解现状并持续优化。有一些基于指标的方法论,建议大家了解一下:

  • Google的四大黄金指标:延迟Latency、流量Traffic、错误Errors、饱和度Saturation
  • Netflix的USE方法:使用率Utilization、饱和度Saturation、错误Error
  • WeaveCloud的RED方法:速率Rate、错误Errors、耗时Duration

二、在SrpingBoot中引入prometheus

SpringBoot2.x集成Prometheus非常简单,首先引入maven依赖:

io.micrometer
micrometer-registry-prometheus
1.7.3
io.github.mweirauch
micrometer-jvm-extras
0.2.2

然后,在application.properties中将prometheus的endpoint放出来。

management:
  endpoints:
    web:
      exposure:
        include: info,health,prometheus

接下来就可以进行指标埋点了,Prometheus的四种指标类型此处不再赘述,请自行学习。一般指标埋点代码实现上有两种形式:AOP、侵入式,建议尽量使用AOP记录指标,对于无法使用aop的场景就只能侵入代码了。常用的AOP方式有:

  • @Aspect(通用)
  • HandlerInterceptor (SpringMVC的拦截器)
  • ClientHttpRequestInterceptor (RestTemplate的拦截器)
  • DubboFilter (dubbo接口)

我们选择通用的@Aspect,结合自定义指标注解来实现。首先自定义指标注解:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodMetrics {
    String name() default "";
    String desc() default "";
    String[] tags() default {};
    //是否记录时间间隔
    boolean withoutDuration() default false;
}

然后是切面实现:

@Aspect
public class PrometheusAnnotationAspect {

    @Autowired
    private MeterRegistry meterRegistry;

    @Pointcut("@annotation(com.smac.prometheus.annotation.MethodMetrics)")
    public void pointcut() {}

    @Around(value = "pointcut()")
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
        Method targetMethod = ((MethodSignature) joinPoint.getSignature()).getMethod();
        Method currentMethod = ClassUtils.getUserClass(joinPoint.getTarget().getClass()).getDeclaredMethod(targetMethod.getName(), targetMethod.getParameterTypes());
        if (currentMethod.isAnnotationPresent(MethodMetrics.class)) {
            MethodMetrics methodMetrics = currentMethod.getAnnotation(MethodMetrics.class);
            return processMetric(joinPoint, currentMethod, methodMetrics);
        } else {
            return joinPoint.proceed();
        }
    }

    private Object processMetric(ProceedingJoinPoint joinPoint, Method currentMethod, MethodMetrics methodMetrics) {
        String name = methodMetrics.name();
        if (!StringUtils.hasText(name)) {
            name = currentMethod.getName();
        }
        String desc = methodMetrics.desc();
        if (!StringUtils.hasText(desc)) {
            desc = currentMethod.getName();
        }
        //不需要记录时间
        if (methodMetrics.withoutDuration()) {
            Counter counter = Counter.builder(name).tags(methodMetrics.tags()).description(desc).register(meterRegistry);
            try {
                return joinPoint.proceed();
            } catch (Throwable e) {
                throw new IllegalStateException(e);
            } finally {
                counter.increment();
            }
        }
        //需要记录时间(默认)
        Timer timer = Timer.builder(name).tags(methodMetrics.tags()).description(desc).register(meterRegistry);
        return timer.record(() -> {
            try {
                return joinPoint.proceed();
            } catch (Throwable e) {
                throw new IllegalStateException(e);
            }
        });
    }
}

代码很容易,没什么可说明的,接下来就是在需要记监控的地方加上这个注解就行,比如:

@MethodMetrics(name="sms_send",tags = {"vendor","aliyun"})
public void send(String mobile, SendMessage message) throws Exception {
    ...
}

至此,aop形式的指标实现方式就完成了。如果是侵入式的话,直接使用meterRegistry就行:

meterRegistry.counter("sms.send","vendor","aliyun").increment();

启动服务,打开http://localhost:8080/actuator/prometheus查看指标。

三、高级指标之分位数

分位数(P50/P90/P95/P99)是我们常用的一个性能指标,Prometheus提供了两种解决方案:

client侧计算方案

summery类型,设置percentiles,在本地计算出Pxx,作为指标的一个tag被直接收集。

Timer timer = Timer.builder("sms.send").publishPercentiles(0.5, 0.9, 0.95,0.99).register(meterRegistry);
timer.record(costTime, TimeUnit.MILLISECONDS);

会出现四个带quantile的指标,如图:

server侧计算方案

开启histogram,将所有样本放入buckets中,在server侧通过histogram_quantile函数对buckets进行实时计算得出。注意:histogram采用了线性插值法,buckets的划分对误差的影响比较大,需合理设置。

Timer timer = Timer.builder("sms.send")
                .publishPercentileHistogram(true)
                .serviceLevelObjectives(Duration.ofMillis(10),Duration.ofMillis(20),Duration.ofMillis(50))
                .minimumExpectedValue(Duration.ofMillis(1))
                .maximumExpectedValue(Duration.ofMillis(100))
                .register(meterRegistry);
timer.record(costTime, TimeUnit.MILLISECONDS);

会出现一堆xxxx_bucket的指标,如图:

然后,使用

histogram_quantile(0.95, rate(sms_send_seconds_bucket[5m]))

就可以看到P95的指标了,如图:

结论:

方案1适用于单机或只关心本地运行情况的指标,比如gc时间、定时任务执行时间、本地缓存更新时间等;

方案2则适用于分布式环境下的整体运行情况的指标,比如搜索接口的响应时间、第三方接口的响应时间等。

到此这篇关于SpringBoot 使用Prometheus采集自定义指标数据的文章就介绍到这了,更多相关SpringBoot采集自定义指标数据内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python如何获取Prometheus监控数据

    目录 获取Prometheus监控数据 获取Prometheus target数据 获取Prometheus 监控信息(cpu.mem.disks) 通过promsql读取prometheus内的数据 获取Prometheus监控数据 获取Prometheus target数据 调用http://<prometheus.address>/api/v1/targets并解析. def getTargetsStatus(address):     url = address + '/api/v1/

  • docker 搭建基于prometheus的监控体系步骤实现

    目录 1.启动prometheus容器服务 2.启动成功后,公网访问该9090端口进入普罗米修斯主页 3.部署mysqld-exporer监控mysql数据库(想监控什么就部署对应的exporter即可) 4.重启prometheus服务 5.访问prometheus主页查看mysql的监控 6.将监控数据通过grafana面板展示 Prometheus是一个时间序列数据库.但是,它不仅仅是一个时间序列数据库. 它涵盖了可以绑定的整个生态系统工具集及其功能. Prometheus主要用于对基础设

  • Prometheus Operator架构介绍

    目录 Prometheus 架构 Prometheus Operator 架构 Prometheus 架构 本节讨论 Prometheus Operator 的架构. 因为 Prometheus Operator 是基于 Prometheus 的,我们需要先了解一下 Prometheus. Prometheus 是一个非常优秀的监控工具.准确的说,应该是监控方案.Prometheus 提供了数据搜集.存储.处理.可视化和告警一套完整的解决方案. Prometheus 的架构如下图所示: 官网上的

  • Prometheus和NodeExporter安装监控数据说明

    目录 在mac下载安装prometheus mac下安装Node Exporter 数据说明 在mac下载安装prometheus 在https://prometheus.io/download/下载prometheus放到自定义的位置. 解压压缩包 创建data文件夹mkdir -p data mac下安装Node Exporter (NodeExporter是Prometheus提供的一个可以采集到主机信息的应用程序,它能采集到机器的 CPU.内存.磁盘等信息) cd到目标目录,然后用命令下

  • Prometheus监控实战篇Nginx、Hbase操作详解

    目录 一.Prometheus监控Nginx 1.监控Nginx相关插件下载地址 2.编译Nginx 2.1下载nginx-release并解压 2.2解压Nginx-module-vts,到/opt/nginx/ 2.3执行以下命令,进行编译Nginx 2.4再执行make命令 2.6在Nginx添加以下内容到Nginx配置文件中 2.7重新启动Nginx,并检查服务是否正常 2.8解压Nginx-vts-exporter,并启动 2.9在Prometheus中添加Nginx-vts-expo

  • prometheus监控节点程序的安装及卸载命令

    目录 安装监控服务 卸载监控程序 本教程基于AlpineLinux,请注意将apk相关命令替换为对应系统的包命令,比如apt.yum等. 安装监控服务 apk add prometheus-node-exporter rc-update add node-exporter default # 配置节点 ARGS="--collector.processes --web.listen-address=:2910 --web.config=/etc/prometheus/web-config.yml

  • SpringBoot 使用Prometheus采集自定义指标数据的方案

    目录 一.我们需要什么指标 二.在SrpingBoot中引入prometheus 三.高级指标之分位数 我们在k8s集群成功搭建了Prometheus服务.今天,我们将在springboot2.x中使用prometheus记录指标. 一.我们需要什么指标 对于DDD.TDD等,大家比较熟悉了,但是对于MDD可能就比较陌生了.MDD是Metrics-Driven Development的缩写,主张开发过程由指标驱动,通过实用指标来驱动快速.精确和细粒度的软件迭代.MDD可使所有可以测量的东西都得到

  • Prometheus 入门教程之SpringBoot 实现自定义指标监控

    上篇文章我们已经可以在 Grafana 上看到对应的 SpringBoot 应用信息了,通过这些信息我们可以对 SpringBoot 应用有更全面的监控.但是如果我们需要对一些业务指标做监控,我们应该怎么做呢?这篇文章就带你一步步实现一个模拟的订单业务指标监控. 假设我们有一个订单系统,我们需要监控它的实时订单总额.10 分钟内的下单失败率.请求失败数.那么我们应该怎么做呢? 添加业务监控指标 在 spring-web-prometheus-demo 项目的基础上,我们添加一个 Promethe

  • 使用 prometheus python 库编写自定义指标的方法(完整代码)

    虽然 prometheus 已有大量可直接使用的 exporter 可供使用,以满足收集不同的监控指标的需要.例如,node exporter可以收集机器 cpu,内存等指标,cadvisor可以收集容器指标.然而,如果需要收集一些定制化的指标,还是需要我们编写自定义的指标. 本文讲述如何使用 prometheus python 客户端库和 flask 编写 prometheus 自定义指标. 安装依赖库 我们的程序依赖于flask和prometheus client两个库,其 requirem

  • SpringBoot快速集成jxls-poi(自定义模板,支持本地文件导出,在线文件导出)

    在项目持续集成的过程中,有时候需要实现报表导出和文档导出,类似于excel中这种文档的导出,在要求不高的情况下,有人可能会考虑直接导出csv文件来简化导出过程.但是导出xlsx文件,其实过程相对更复杂.解决方案就是使用poi的jar包.使用源生的poi来操作表格,代码冗余,处理复杂,同时poi的相关联的依赖还会存在版本兼容问题.所以直接使用poi来实现表格导出,维护成本大,不易于拓展. 我们需要学会站在巨人的肩膀上解决问题,jxls-poi这个就很好解决这个excel表格导出的多样化的问题.类似

  • SpringBoot自动配置之自定义starter的实现代码

    前言:前面已经介绍了自动配置的很多原理,现在我们着手自己定义一个starter. 需求:自定义redis-starter,要求当导入redis坐标后,SpringBoot自动创建Jedis的Bean.正式开始之前,我们可以查看Mybatis的起步依赖是如果实现自动配置的.我这里就省略了,大家根据之前的分析文章,自己看源码即可. 一.先创建一个SpringBoot工程redis-spring-boot-autoconfigure,该工程中添加jedis依赖,并且创建一个自动配置类RedisAuto

  • Vue向后台传数组数据,springboot接收vue传的数组数据实例

    用axios前台代码: let menus_id = this.$refs.tree.getCheckedKeys(); //菜单id [1,2,3]数组 this.$axios.get("/api/epidemic/roleMenus/addBath1",{params:{roleid:this.roleid,menusid:menus_id}}).then((result)=>{ console.log(result) }) 后台代码: @RequestMapping(&qu

  • SpringBoot 拦截器和自定义注解判断请求是否合法

    应用场景举例: 当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释 自定义注解 /** * 对比请求的用户身份是否符合 * @author liuyalong * @date 2020/9/25 16:03 */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface CompareUser { /** * The name

  • 详解如何为SpringBoot项目中的自定义配置添加IDE支持

    导言 代码是写给人看的,不是写给机器看的,只是顺便计算机可以执行而已 --<计算机程序的构造和解释(SICP)> 导言 在我们的项目里经常会出现需要添加自定义配置的应用场景,例如某个开关变量,在测试环境打开,在生产环境不打开,通常我们都会使用下面的代码来实现,然后在Spring Boot配置文件中添加这个key和Value Application.java: application.properties 或者是没有使用@Value而直接在XML中使用我们配置的属性值 application.x

  • SpringBoot使用prometheus监控的示例代码

    本文介绍SpringBoot如何使用Prometheus配合Grafana监控. 1.关于Prometheus Prometheus是一个根据应用的metrics来进行监控的开源工具.相信很多工程都在使用它来进行监控,有关详细介绍可以查看官网:https://prometheus.io/docs/introduction/overview/. 2.有关Grafana Grafana是一个开源监控利器,如图所示. 从图中就可以看出来,使用Grafana监控很高大上,提供了很多可视化的图标. 官网地

  • springboot中如何使用自定义两级缓存

    工作中用到了springboot的缓存,使用起来挺方便的,直接引入redis或者ehcache这些缓存依赖包和相关缓存的starter依赖包,然后在启动类中加入@EnableCaching注解,然后在需要的地方就可以使用@Cacheable和@CacheEvict使用和删除缓存了.这个使用很简单,相信用过springboot缓存的都会玩,这里就不再多说了.美中不足的是,springboot使用了插件式的集成方式,虽然用起来很方便,但是当你集成ehcache的时候就是用ehcache,集成redi

随机推荐