在SpringBoot中自定义指标并使用Prometheus监控报警

公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享

在10 分钟教你使用Prometheus监控Spring Boot工程中介绍了如何使用Prometheus监控Spring Boot提供的默认指标,这篇介绍如何自定义业务指标,并使用Prometheus进行监控并报警,同时在 Grafana 进行展现

示例介绍

我们模拟一个账务系统,主要功能有:充值与提现,其中会定义5 个业务指标,如下

  • 充值次数
  • 充值金额
  • 提现次数
  • 提现金额
  • 余额

针对以上5 业务指标,会使用prometheus的三种Metrics类型,如下

  1. Counter:只增不减的计数器,用作定义充值次数提现次数

  2. Gauge:可增可减的仪表盘,侧重于反应系统的当前状态,用作定义余额

  3. Summary:用于记录某些东西的平均大小,也可以计算总和,用作定义充值金额提现金额

最终我们对以上指标进行 grafana 进行展现,同时对余额小于500 进行告警通知,效果如下

监控与验证

Spring Boot 工程配置
  1. 添加 maven 依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
  1. 在application.properties,开启监控的端点
#监控的端点
management.endpoints.web.exposure.include=*
#应用程序名称,在prometheus 上会显示
management.metrics.tags.application=${spring.application.name}
#tomcat 指标需要开启
server.tomcat.mbeanregistry.enabled=true
  1. 编写业务代码,提供体现和充值方法,并在init方法中定义五个业务指标,使用了三种Metrics类型
@Service
@Slf4j
public class AccountServiceImpl implements IAccountService {@Autowiredprivate MeterRegistry registry;//入金笔数private Counter depositCounter; // 出金笔数private Counter withdrawCounter; //入金金额private DistributionSummary depositAmountSummary;// 出金金额private DistributionSummary withdrawAmountSummary; //余额private BigDecimal balance = new BigDecimal(1000);@PostConstructprivate void init() {depositCounter = registry.counter("deposit_counter", "currency", "btc");withdrawCounter = registry.counter("withdraw_counter", "currency", "btc");depositAmountSummary = registry.summary("deposit_amount", "currency", "btc");withdrawAmountSummary = registry.summary("withdraw_amount", "currency", "btc");Gauge.builder("balanceGauge", () -> balance).tags("currency", "btc").description("余额").register(registry);}@Override// 充值操作public void depositOrder(BigDecimal amount) {log.info("depositOrder amount:{}", amount);try {//余额增加balance = balance.add(amount);//充值笔数埋点depositCounter.increment();//充值金额埋点depositAmountSummary.record(amount.doubleValue());} catch (Exception e) {log.info("depositOrder error", e);} finally {log.info("depositOrder result:{}", amount);}}@Override//提现操作public void withdrawOrder(BigDecimal amount) {log.info(" withdrawOrder amount:{}", amount);try {if (balance.subtract(amount).compareTo(BigDecimal.ZERO) < 0) {throw new Exception("提现金额不足,提现失败");}//余额减少balance = balance.subtract(amount);// 提现笔数埋点数据withdrawCounter.increment();// 提现金额埋点withdrawAmountSummary.record(amount.doubleValue());} catch (Exception e) {log.info("withdrawOrder error", e);} finally {log.info("withdrawOrder result:{}", amount);}}}
  1. Controller 方法,定义了充值提现接口
@RestController
@RequestMapping(ControllerConstants.PATH_PREFIX + "/account")
public class AccountController {@AutowiredIAccountService accountService;/*** 充值*/@RequestMapping(value = "/deposit", method = RequestMethod.GET)public void deposit(@RequestParam("amount") BigDecimal amount) {accountService.depositOrder(amount);}/*** 提现*/@RequestMapping(value = "/withdraw", method = RequestMethod.GET)public void withdraw(@RequestParam("amount") BigDecimal amount) {accountService.withdrawOrder(amount);}}
  1. 启动服务查看,访问actuator/prometheus接口,如果能查询以下指标则配置成功

    ##充值笔数
    deposit_counter_total
    ## 充值总金额
    deposit_amount_sum
    ##提现笔数
    withdraw_counter_total
    ##提现总金额
    withdraw_amount_sum
    ## 余额
    balanceGauge
    

Promethues 配置
  1. prometheus.yml文件中进行配置业务系统采集点,5s 拉取一次指标,由于prometheus server 部署在docker 中,所以访问主机IP 用host.docker.internal

    #业务系统监控          - job_name: 'SpringBoot'# Override the global default andscrape_interval: 5smetrics_path: '/actuator/prometheus'static_configs:- targets: ['host.docker.internal:8080']       
    

  1. 告警规则配置,在容器启动时用主机的/data/prometheus目录映射到容器的/prometheus目录,因此在主机/data/prometheus/目录创建rules文件夹,并创建告警文件business-alert.rules,这里告警对余额小于 500 则进行告警

    groups:
    - name: businessAlertrules:- alert: balanceAlertexpr: balanceGauge{application="backend"} < 500for: 20slabels:severity: pageteam: g2parkannotations:summary: "{{ $labels.currency }} balance is insufficient "description: "{{ $labels.currency }} balance : {{ $value }}"
    
  2. 启动Prometheus,进行验证,查询采集目标,已生效

    查询充值次数,已采集

    点击Alters,可以看到业务告警已经生效

AlterManager配置
  1. /data/prometheus/alertmanager目录下,新增告警模板notify-template.tmpl,此目录映射到altermanager 的/etc/alertmanager目录,模板包含告警和自愈两部分,2006-01-02 15:04:05是go语言的日志格式,固定值,加28800e9表示转换为东八区时间,即北京时间

    {{ define "test.html" }} 
    {{- if gt (len .Alerts.Firing) 0 -}}
    {{ range .Alerts }}
    <h1 align="left" style="color:red;">告警</h1>
    <pre>
    告警级别: {{ .Labels.severity }} 级 <br>
    告警类型: {{ .Labels.alertname }} <br>
    故障主机: {{ .Labels.instance }} <br>
    告警主题: {{ .Annotations.summary }} <br>
    告警详情: {{ .Annotations.description }} <br>
    告警时间:{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br>  
    </pre>
    {{ end }}
    {{ end }}
    {{- if gt (len .Alerts.Resolved) 0 -}}
    {{ range .Alerts }}
    <h1 align="left" style="color:green;">恢复</h1>
    <pre>
    告警名称:{{ .Labels.alertname }}<br>
    告警级别:{{ .Labels.severity }}<br>
    告警机器:{{ .Labels.instance }}<br>
    告警主题:{{ .Annotations.summary }}<br>
    告警主题:{{ .Annotations.description }}<br>
    告警时间:{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br> 
    恢复时间:{{ (.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br> 
    </pre>
    {{- end }}
    {{- end }}
    {{- end }}
    
  2. 修改alertmanager.yml为以下内容,替换对应账号即可

    global:smtp_smarthost: smtp.qq.com:465smtp_from: 9238223@qq.comsmtp_auth_username: 9238223@qq.comsmtp_auth_identity: 9238223@qq.comsmtp_auth_password: 123smtp_require_tls: false
    templates: #添加模板- '/etc/alertmanager/notify-template.tmpl'   #指定路径    
    route:group_by: ['alertname']receiver: 'default-receiver'group_wait: 30sgroup_interval: 5mrepeat_interval: 1h
    receivers:- name: default-receiveremail_configs:- to: abc123@foxmail.comhtml: '{{ template "test.html" . }}'send_resolved: trueheaders: { Subject: "系统监控告警{{- if gt (len .Alerts.Resolved) 0 -}}恢复{{ end }}" }  
    

    global: 这是一个全局配置部分,用于配置全局的Alertmanager设置。

    • smtp_smarthost: 这是SMTP服务器的地址和端口,用于发送邮件通知。
    • smtp_from: 这是邮件发送方的邮件地址,即发送邮件的地址。

    route: 用于配置警报的路由规则。

    • group_by: ['alertname']: 这是一个标签列表,用于按照警报名称(alertname)进行分组。
    • receiver: 'default-receiver': 这是指定默认接收者的名称,即接收警报通知的收件人。
    • group_wait: 30s: 在发送警报通知前等待的时间,以便将相同的警报分组在一起。
    • group_interval: 5m: 这是发送同一组警报通知之间的最小时间间隔。
    • repeat_interval: 1h: 这是在重复发送未解决的警报通知之前等待的时间间隔。

    receivers: 接收者部分,用于配置接收告警通知的收件人。

    • name: default-receiver: 这是默认接收者的名称。

    • email_configs: 用于指定接收邮件通知的收件人和其他相关设置。

      • to: abc123@foxmail.com: 这是收件人的邮件地址,即接收警报通知的邮箱地址。

      • send_resolved: true: 这是一个布尔值,指示是否发送已解决的警报通知。在这个例子中,设置为true,表示发送已解决的警报通知。

  3. 启动Altermanager,进行验证

    docker start alertmanager
    

    访问stauts,如果出现以下结果则成功

  4. 告警验证,系统默认余额为1000,调用backend/account/withdraw提现接口,使余额降至500,进行报警

​ 等待20s 左右,prometheus 收到报警会推送至Altermanager

Altermanager则会根据我们配置时间等待 30s,进行通知告警

  1. 自愈验证,调用充值backend/account/deposit接口,使余额大于500,等待6m 左右会收到自愈告警,如果嫌时间比较长,修改alertmanager.yml中 group_waitgroup_interval参数值即可

Grafana配置

启动 Grafana,点击新增面板,创建三种图表,分别为余额走势提现与充值金额占比提现与充值笔数走势图,如下

image-20231228222038158

余额走势,报表类型为Stat

sum(balanceGauge{application="backend"})

提现与充值金额占比,报表类型为Pie chart

withdraw_amount_sum{application="backend"}
deposit_amount_sum{application="backend"}

提现与充值笔数走势图,报表类型为Time series

increase(deposit_counter_total{application="backend"}[5m])
increase(withdraw_counter_total{application="backend"}[5m])

总结

以上介绍了如何在Spring Boot中自定义业务指标以及对指标进行监控和告警,希望对你所帮助,注意以上示例只是为了简单便于理解才是这样写,真实使用中,指标可以与数据库或者缓存进行结合,比如余额报警,调用查询余额接口即可。

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

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

相关文章

秋招复习篇之代码规范

目录 前言 1、变量命名 2、代码空格 1&#xff09;操作符左右一定有空格&#xff0c; 2&#xff09;分隔符&#xff08;, 和;&#xff09;前一位没有空格&#xff0c;后一位保持空格&#xff0c;例如&#xff1a; 3&#xff09;大括号和函数保持同一行&#xff0c;并有一个空格…

JavaScript Class类 | 类的继承 - 类的使用 -原型与原型链

文章目录 JavaScript class类基础概念属性与方法相关概念私有字段类的name属性 返回类的名字类的访问器方法super关键字 new的过程中发生了什么extends继承 重写-重载 语法细节类声明与类表达式补充理解:let和const的作用域提升规则 类的继承原型与隐式原型链特殊原型链 原型链…

【C++核心编程(一)】

一、内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域&#xff1a; 代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理的。 全局区&#xff1a;存放全局变量和静态变量以及常量。 栈区&#xff1a;由编译器自动分配释放,存放函数的…

第52周,第三期技术动态

大家好&#xff0c;才是真的好。 今天周五&#xff0c;我们主要介绍与Domino相关产品新闻&#xff0c;以及互联网或其他IT行业动态等。 一、HCL Domino将重新开发和发布应用市场 为了持续吸引新客户&#xff0c;现有客户以及技术爱好者和专业人士&#xff0c;在2023年的 Col…

6种大模型的使用方式总结,使用领域数据集持续做无监督预训练可能是一个好选择

本文原文来自DataLearnerAI官方网站&#xff1a;6种大模型的使用方式总结&#xff0c;使用领域数据集持续做无监督预训练可能是一个好选择 | 数据学习者官方网站(Datalearner)https://www.datalearner.com/blog/1051703426665726 Sebastian Raschka是LightningAI的首席科学家&…

数字身份验证:跨境电商如何应对账户安全挑战?

在数字化时代&#xff0c;随着跨境电商的蓬勃发展&#xff0c;账户安全问题逐渐成为行业和消费者关注的焦点。随着网络犯罪日益猖獗&#xff0c;用户的数字身份安全面临着更加复杂的威胁。本文将深入探讨数字身份验证在跨境电商中的重要性&#xff0c;并探讨各种创新技术和策略…

前端使用高德api的AMap.Autocomplete无效,使用AMap.Autocomplete报错

今天需要一个坐标拾取器&#xff0c;需要一个输入框输入模糊地址能筛选的功能 查看官方文档&#xff0c;有一个api可以直接满足我们的需求 AMap.Autocomplete 上代码 AMapLoader.load({"key": "你的key", // 申请好的Web端开发者Key&#xff0c;首次调…

XHR与Fetch的功能异同点列表

XHR与Fetch的功能异同点列表

2012年第一届数学建模国际赛小美赛B题大规模灭绝尚未到来解题全过程文档及程序

2012年第一届数学建模国际赛小美赛 B题 大规模灭绝尚未到来 原题再现&#xff1a; 亚马逊是地球上现存最大的雨林&#xff0c;比地球上任何地方都有更多的野生动物。它位于南美洲大陆的北侧&#xff0c;共有9个国家&#xff1a;巴西、玻利维亚、厄瓜多尔、秘鲁、哥伦比亚、委…

哪种猫粮比较好?超能打的5款主食冻干测评

不知道从什么时候开始掀起一股冻干喂养风&#xff0c;各种查资料阅读文献发现冻干喂养是最适合忙碌地打工人的“生骨肉喂养”替代版&#xff0c;是最符合猫咪饮食天性的一种。很多养猫人纷纷开始冻干喂养&#xff0c;但对于主食冻干猫粮的选择就让很多猫奴犯了难在电商平台随便…

Opencascad(C++)-判断直线段与TopoDS_Shape是否相交(干涉)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1、前言2、根据两个点创建有界直线段3、判断TopoDS_Shape与直线段相交 1、前言 最近在研究Opencascad的开发&#xff0c;有个需求是判断直线与TopoDS_Shpae是否存在…

0开始配置Cartographer建图和导航定位

0开始配置Cartographer 日期&#xff1a;12-19 硬件&#xff1a;激光雷达IMU 小车的tf变换&#xff1a; 建图配置 lua文件配置&#xff1a;my_robot.lua include "map_builder.lua" include "trajectory_builder.lua"options {map_builder MAP_BUILDE…