《SpringBoot 整合 Prometheus 采集自定义指标》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,如需交流,欢迎留言评论。👍

文章目录

    • 写在前面的话
    • SpringBoot 整合 Prometheus
    • 继续采集 OkHttp3 指标
    • 整合 Grafana
    • 关于 PromQL 语法
    • 总结陈词


写在前面的话

前不久博主整理了 《企业实战分享 · 常用运维中间件》,提到一些常用的中间件,这回介绍一下代码层面的具体整合工作。
此篇博文先介绍一下SpringBoot如何整合Prometheus采集自定义指标,各位大佬可以自行发散。


SpringBoot 整合 Prometheus

背景说明:这里默认已经准备好一个完整的SpringBoot项目,并且已经整合了Druid,这里以采集Druid指标为例介绍整合流程。

Step1、添加 Pom 依赖

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

Step2、在 application.yml 中配置 Actuator 和 Prometheus

management:endpoints:web:exposure:# 仅暴露 prometheus、health 和 info 端点。include: prometheus, health, infometrics:export:prometheus:# 启用 Prometheus 指标导出。enabled: trueendpoint:prometheus:# 启用 /prometheus 端点。enabled: true

Step3、注册 Druid 数据源的指标到 Micrometer

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(DruidDataSource.class)
static class DruidDataSourcePoolMetadataProviderConfiguration implements SmartInitializingSingleton {private DruidDataSource wrappedDataSource;@Beanpublic DataSourcePoolMetadataProvider druidPoolDataSourceMetadataProvider() {return (dataSource) -> {DruidDataSource ds = DataSourceUnwrapper.unwrap(dataSource, DruidDataSource.class);if (ds != null) {this.wrappedDataSource = ds;return new DruidDataSourcePoolMetadata(ds);}return null;};}@Overridepublic void afterSingletonsInstantiated() {if (this.wrappedDataSource == null) {return;}Metrics.gauge(MetricsConstant.DataSource.POOLING_COUNT, this.wrappedDataSource, DruidDataSource::getPoolingCount);Metrics.gauge(MetricsConstant.DataSource.CONNECT_OPEN_COUNT, this.wrappedDataSource, DruidDataSource::getConnectCount);Metrics.gauge(MetricsConstant.DataSource.CONNECT_CLOSE_COUNT, this.wrappedDataSource, DruidDataSource::getCloseCount);Metrics.gauge(MetricsConstant.DataSource.CONNECT_ERROR_COUNT, this.wrappedDataSource, DruidDataSource::getConnectErrorCount);Metrics.gauge(MetricsConstant.DataSource.EXECUTE_COUNT, this.wrappedDataSource, DruidDataSource::getExecuteCount);Metrics.gauge(MetricsConstant.DataSource.ROLLBACK_COUNT, this.wrappedDataSource, DruidDataSource::getRollbackCount);Metrics.gauge(MetricsConstant.DataSource.PHYSICAL_CONNECT_COUNT, this.wrappedDataSource, DruidDataSource::getCreateCount);Metrics.gauge(MetricsConstant.DataSource.PHYSICAL_CLOSE_COUNT, this.wrappedDataSource, DruidDataSource::getDestroyCount);Metrics.gauge(MetricsConstant.DataSource.PHYSICAL_CONNECT_ERROR_COUNT, this.wrappedDataSource, DruidDataSource::getCreateErrorCount);Metrics.gauge(MetricsConstant.DataSource.NOT_EMPTY_WAIT_COUNT, this.wrappedDataSource, DruidDataSource::getNotEmptyWaitCount);Metrics.gauge(MetricsConstant.DataSource.NOT_EMPTY_WAIT_MILLIS, this.wrappedDataSource, DruidDataSource::getNotEmptyWaitMillis);}
}

Step4、配置 Prometheus 抓取 Spring Boot 应用的指标
进入Prometheus所在服务器,修改配置文件prometheus.yml
如下所示,是配置具体某个服务,如果是SpringCloud,有接入网关,也可以通过网关配置。

scrape_configs:- job_name: 'spring-boot-app'static_configs:- targets: ['localhost:8080']

Step5、启动 Spring Boot 应用并检查指标
访问地址:http://127.0.0.1:28888//actuator/prometheus
应该可以看到如下图所示的相关指标信息,包括 Druid 数据源的指标。
image.png

Step6、打开 Prometheus 界面验证
启动 Prometheus,访问地址:http://localhost:9090
在 Prometheus 的界面中可以看到从 Spring Boot 应用中抓取到的指标数据,操作效果如下图:
image.png


继续采集 OkHttp3 指标

需求背景
框架采用OkHttp3作为远程调用工具,现在也需要采集相关指标到Prometheus
这里基本实现思路,类似前面的Druid整合方案。
1、瞬时类型的指标,可以在初始化的时候利用Metrics.gauge注册;
2、请求耗时这样的指标,可以借助 OkHttp3 的拦截器,计算耗时,再利用Metrics.timer注册;

Metrics.gauge 和 Metrics.timer 区别
Metrics.gauge 收集的是瞬时数据(instantaneous data),也就是某一时刻的数值。这些数据通常反映了当前状态或当前值,例如内存使用量、线程数、队列长度等。
Metrics.timer 收集的是区间数据(interval data),也就是一段时间内的多个数据点。这些数据点可以用于计算统计信息,比如平均值、最小值、最大值等。
通过这两种不同的度量方式,可以全面地监控和分析应用程序的性能和状态。

具体代码案例

public class HttpClientMetricsInterceptor implements Interceptor {public HttpClientMetricsInterceptor(Dispatcher dispatcher) {Assert.notNull(dispatcher, "OkHttp dispatcher could not be null");Metrics.gauge(HttpClient.MAX_REQ_PER_HOST_SIZE, dispatcher.getMaxRequestsPerHost());Metrics.gauge(HttpClient.MAX_REQ_SIZE, dispatcher.getMaxRequests());Metrics.gauge(HttpClient.REQ_RUNNING_COUNT, dispatcher, Dispatcher::runningCallsCount);Metrics.gauge(HttpClient.REQ_QUEUE_TASK_COUNT, dispatcher, Dispatcher::queuedCallsCount);ExecutorService executorService = dispatcher.executorService();if (executorService instanceof ThreadPoolExecutor) {ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;Metrics.gauge(HttpClient.MAX_POOL_SIZE, executor, ThreadPoolExecutor::getMaximumPoolSize);Metrics.gauge(HttpClient.CORE_POOL_SIZE, executor, ThreadPoolExecutor::getCorePoolSize);Metrics.gauge(HttpClient.ACTIVE_POOL_COUNT, executor, ThreadPoolExecutor::getActiveCount);Metrics.gauge(HttpClient.LARGEST_POOL_SIZE, executor, ThreadPoolExecutor::getLargestPoolSize);}}@Overridepublic Response intercept(Chain chain) throws IOException {Timer.Sample sample = Timer.start(Metrics.globalRegistry);Request request = chain.request();Response response = null;try {response = chain.proceed(request);} finally {String threadName = Thread.currentThread().getName();boolean async = StrUtil.startWith(threadName, "okhttp", true);Timer timer = Metrics.timer(HttpClient.RESP_TIME,"method", request.method(),"status", String.valueOf(response == null ? "-1" : response.code()),"uri", URLUtil.getPath(request.url().toString()),"async", async + "");sample.stop(timer);}return response;}}

整合 Grafana

采集到Prometheus的数据,可以通过界面操作,但如果想以仪表盘的直观形式展示更多指标信息,可以考虑整合Grafana,整合工作很简单,代码不需要任何改动。
只需要按如下步骤:

  • 安装并启动 Grafana。
  • 配置 Prometheus 数据源。
  • 创建或导入 Dashboard。
  • 使用 Prometheus 查询语法可视化指标。
  • 根据需要配置告警和通知。

企业微信截图_17089126918229.png
相关博文:《企业实战分享 · 常用运维中间件》


关于 PromQL 语法

使用Prometheus界面查询的时候,需要借助PromQL语法,一般使用Prometheus查询自定义指标。
通过指标建议通过Grafana面板查询更直观。
下方是一些查询示例:

语法:<metric name>{<label name>=<label value>, ...}
示例一:onelink_datasource_poolingCount{application="archive-service"}[20s] offset 1m
示例分析:
1、onelink_datasource_poolingCount是指标名称,是自定义指标,代表“当前连接池中的连接数”;
2、{application="archive-service"}大括号代表过滤,很好理解;
3、[20s]中括号代表时间范围,没添加时间的代表瞬时向量查询,添加了时间的代表区间向量查询,右侧Value会出现多个值,值的个数等于指定时间/拉取频率,例如开发库指定10秒拉取,则出现2个值。
4、offset代表时间位移,不添加代表以当前系统时间为基准进行查询;示例二:
count(onelink_datasource_poolingCount{application="archive-service"} > 1)
rate(onelink_datasource_poolingCount{application="archive-service"}[1m]) --1分钟增长
topk(6, onelink_datasource_poolingCount > 3) -- 查看前6的指标
示例分析:
1、通过布尔运算对时间序列进行过滤,其实就是上面示例二的大于号,将value进行比对;
2、可以使用一些函数,具体看示例;过滤符号补充:
label=value 完全匹配
label!=value 完全不陪陪
label=~regx 正则匹配
label=!~regx 正则不匹配
onelink_datasource_poolingCount{application=~"archive-service|dc-.*"}时间单位补充:
s - 秒
m - 分钟
h - 小时
d - 天
w - 周
y - 年布尔运算补充:
== (相等)
!= (不相等)
> (大于)
< (小于)
>= (大于等于)
<= (小于

总结陈词

上文分享若干企业实际开发中日常使用场景及应对方案,希望对大家有帮助。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/376854.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dataset for Stable Diffusion

1.Dataset for Stable Diffusion 笔记来源&#xff1a; 1.Flickr8k数据集处理 2.处理Flickr8k数据集 3.Github&#xff1a;pytorch-stable-diffusion 4.Flickr 8k Dataset 5.dataset_flickr8k.json 6.About Train, Validation and Test Sets in Machine Learning Tarang Shah …

树莓派pico入坑笔记,ssd1306使用

目录 关于树莓派pico和circuitpython的更多玩法&#xff0c;请看树莓派pico专栏 说明 后附进阶玩法&#xff1a;显示中文&#xff0c;外加简单库实现 官方模块使用 使用样例 方法说明 下面是绘图支持的方法 进阶玩法&#xff0c;显示中文 方法&#xff0c;对汉字取字模…

力扣经典题目之->移除值为val元素的讲解,的实现与讲解

一&#xff1a;题目 博主本文将用指向来形象的表示下标位的移动。 二&#xff1a;思路 1&#xff1a;两个整形&#xff0c;一个start&#xff0c;一个end&#xff0c;在一开始都 0&#xff0c;即这里都指向第一个元素。 2&#xff1a;在查到val之前&#xff0c;查一个&…

基于SSM的校园一卡通管理系统的设计与实现

摘 要 本报告全方位、深层次地阐述了校园一卡通管理系统从构思到落地的整个设计与实现历程。此系统凭借前沿的 SSM&#xff08;Spring、Spring MVC、MyBatis&#xff09;框架精心打造而成&#xff0c;旨在为学校构建一个兼具高效性、便利性与智能化的一卡通管理服务平台。 该系…

聚观早报 | 网宿科技推出边缘AI网关;AMD再收购AI公司

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 7月12日消息 网宿科技推出边缘AI网关 AMD再收购AI公司 谷歌Pixel 9系列将配超声波指纹 三星Galaxy Z Fold6亮相 …

[线性RNN系列] Mamba: S4史诗级升级

前言 iclr24终于可以在openreview上看预印本了 这篇&#xff08;可能是颠覆之作&#xff09;文风一眼c re组出品&#xff1b;效果实在太惊艳了&#xff0c;实验相当完善&#xff0c;忍不住写一篇解读分享分享。 TL;DR &#xff08;overview&#xff09; Structured State-Sp…

【TOOLS】Chrome扩展开发

Chrome Extension Development 1. 入门教程 入门案例&#xff0c;可以访问【 谷歌插件官网官方文档 】查看官方入门教程&#xff0c;这里主要讲解大概步骤 Chrome Extenson 没有固定的脚手架&#xff0c;所以项目的搭建需要根据开发者自己根据需求搭建项目&#xff08;例如通过…

机器学习基本概念,Numpy,matplotlib和张量Tensor知识进一步学习

机器学习一些基本概念&#xff1a; 监督学习 监督学习是机器学习中最常见的形式之一&#xff0c;它涉及到使用带标签的数据集来训练模型。这意味着每条训练数据都包含输入特征和对应的输出标签。目标是让模型学会从输入到输出的映射&#xff0c;这样当给出新的未见过的输入时…

vue学习day09-自定义指令、插槽

29、自定义指令 &#xff08;1&#xff09;概念&#xff1a;自己定义的指令&#xff0c;可以封装一些dom操作&#xff0c;扩展额外的功能。 &#xff08;2&#xff09;分类&#xff1a; 1&#xff09;全局注册 2&#xff09;局部注册 3&#xff09;示例&#xff1a; 让表…

Android Studio启动报错:The emulator process for AVD Pixel_5_API_30 has terminated

Android Studio启动AVD报错&#xff1a; The emulator process for AVD Pixel_5_API_30 has terminated. 原因&#xff1a;安装时使用自定义安装后&#xff0c;修改了默认安装目录。 而avd文件默认在 C:\Users\用户名\.android 目录下。所以导致打开AVD时报错。 解决方法&am…

RABBITMQ的本地测试证书生成脚本

由于小程序要求必须访问wss的接口&#xff0c;因此需要将测试环境也切换到https&#xff0c;看了下官方的文档 RabbitMQ Web STOMP Plugin | RabbitMQ里面有这个信息 然后敲打GPT一阵子&#xff0c;把要求输入几个来回&#xff0c;得到这样一个脚本&#xff1a; generate_cer…

几何建模-Parasolid中GO功能使用

1.背景介绍 1.1 Parasolid和它的接口间关系 1.2 什么是GO GO全称是Graphical Output.你的程序需要在屏幕或者打印设备上显示模型数据时。在需要使用PK中的某个渲染函数时创建图形显示数据时&#xff0c;Parasolid会调用GO相关的函数。GO函数会输出绘图指令给你的应用程序提供…

主机安全-进程、命令攻击与检测

目录 概述反弹shell原理nc/dev/xxx反弹shell下载不落地反弹Shell各种语言反弹shell linux提权sudosuid提权mysql提权 Dnslog参考 概述 本文更新通过在主机&#xff08;不含容器&#xff09;上直接执行命令或启动进程来攻击的场景。检测方面以字节跳动的开源HIDS elkeid举例。每…

Nignx配置

Nginx配置之nginx.conf文件解析及配置 1、nginx.conf文件解析 user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf;events {worker_connections 768;# multi_accept on; }http {### Basic Settings###开启文件的高效传输…

Docker搭建kafka+zookeeper以及Springboot集成kafka快速入门

参考文章 【Docker安装部署KafkaZookeeper详细教程】_linux arm docker安装kafka-CSDN博客 Docker搭建kafkazookeeper 打开我们的docker的镜像源配置 vim /etc/docker/daemon.json 配置 { "registry-mirrors": ["https://widlhm9p.mirror.aliyuncs.com"…

全面升级的对象创建——抽象工厂模式(Python实现和JAVA实现)

1. 引言 大家好&#xff01;在之前的文章中&#xff0c;我们探讨了简单工厂和工厂方法模式&#xff1a; 轻松创建对象——简单工厂模式&#xff08;Python实现&#xff09; 轻松创建对象——简单工厂模式&#xff08;Java实现&#xff09; 灵活多变的对象创建——工厂方法模式…

20240711每日消息队列-------------MQ消息的积压的折磨

目标 解决MQ消息的积压 背景 菜馆系统----------- 系统读取消息&#xff0c;处理业务逻辑&#xff0c;持久化订单和菜品数据&#xff0c;然后将其显示在菜品管理客户端上。 最初我们的用户基数很小&#xff0c;上线后的一段时间内&#xff0c;MQ消息通信还算顺利。 随着用户…

k8s(五)---名称空间

五、名称空间 名称空间是k8s划分不同工作空间的逻辑单位,是k8s资源逻辑隔离的机&#xff0c;。可以给不同的租户&#xff0c;不同的环境、不同的项目创建对应的命名空间。 1、查看名称空间 kubectl get ns kubectl get namespaces 此处展示了四个命名空间 2、管理名称空间 1…

Matlab-Simulink模型保存为图片的方法

有好多种办法将模型保存为图片&#xff0c;这里直接说经常用的 而且贴到Word文档中清晰、操作简单。 simulink自带有截图功能&#xff0c;这两种方法都可以保存模型图片。选择后直接就复制到截切板上了。直接去文档中粘贴就完事了。 这两个格式效果不太一样&#xff0c;第一种清…

[Java IO] 文件的概念与相关操作

一 概念 什么是文件&#xff1f; 文件就是保存数据的地方。 二 文件流 文件在程序中是以流的形式来操作的。 流——数据在数据源&#xff08;文件&#xff09;和程序&#xff08;内存&#xff09;之间经历的路径。 输入流&#xff1a;数据从数据源&#xff08;文件&#…