在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://xiahunao.cn/news/2661793.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

神经网络:模型部署

【一】模型压缩的必要性与可行性&#xff1f; 模型压缩是指对算法模型进行精简&#xff0c;进而得到一个轻量且性能相当的小模型&#xff0c;压缩后的模型具有更小的结构和更少的参数&#xff0c;可以有效降低计算和存储开销&#xff0c;便于部署在端侧设备中。 随着AI技术的…

ERP与智能商品系统在供应链管理上有哪些区别和优势?

ERP系统和智能商品系统在供应链管理方面有以下区别和优势&#xff1a; 范围和综合性&#xff1a;ERP系统涵盖了企业的整个供应链管理过程&#xff0c;包括供应商管理、采购管理、库存管理、生产计划和物流管理等。它可以实现供应链上下游的信息共享和协同&#xff0c;提高供应…

鸿蒙原生应用/元服务开发-Stage模型能力接口(十)下

ohos.app.form.FormExtensionAbility (FormExtensionAbility) 系统能力&#xff1a;SystemCapability.Ability.Form 示例 import FormExtensionAbility from ohos.app.form.FormExtensionAbility; import formBindingData from ohos.app.form.formBindingData; import formP…

【Java干货教程】JSON,JSONObject,JSONArray类详解

一、定义 JSON&#xff1a;就是一种轻量级的数据交换格式&#xff0c;被广泛应用于WEB应用程序开发。JSON的简洁和清晰的层次结构&#xff0c;易于阅读和编写&#xff1b;同时也易于机器解析和生成&#xff0c;有效的提升网络传输效率&#xff1b;支持多种语言&#xff0c;很多…

Java商城 免 费 搭 建:鸿鹄云商实现多种商业模式,VR全景到SAAS,应有尽有!

鸿鹄云商 b2b2c产品概述 【b2b2c平台】&#xff0c;以传统电商行业为基石&#xff0c;鸿鹄云商支持“商家入驻平台自营”多运营模式&#xff0c;积极打造“全新市场&#xff0c;全新 模式”企业级b2b2c电商平台&#xff0c;致力干助力各行/互联网创业腾飞并获取更多的收益。从消…

pdf编辑器:Acrobat Pro DC 2023中文

Acrobat Pro DC 2023是一款功能强大的PDF处理软件&#xff0c;可以帮助用户在创建、编辑、转换和合并PDF文档方面达到前所未有的高度。Acrobat Pro DC 2023具备创建PDF的功能&#xff0c;用户可以将各种类型的文件&#xff0c;如Word、Excel、PowerPoint、图片等&#xff0c;轻…

HTTP与HTTPS的区别,看这一篇就够了

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是网页传输中常用的两种协议&#xff0c;它们之间的主要区别在于安全性。 HTTP是一种用于在Web浏览器和服务器之间传递信息的标准协议。然而&#…

【SpringBoot篇】详解Bean的管理(获取bean,bean的作用域,第三方bean)

文章目录 &#x1f354;Bean的获取&#x1f384;注入IOC容器对象⭐代码实现&#x1f6f8;根据bean的名称获取&#x1f6f8;根据bean的类型获取&#x1f6f8;根据bean的名称和类型获取 &#x1f384;Bean的作用域⭐代码实现&#x1f388;注意 &#x1f384;第三方Bean⭐代码实现…

【Unity动画系统】Animator有限状态机参数详解

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

怎么快速去除图片水印?这些快速去除的工具赶紧码住

在数字时代的大潮中&#xff0c;图片与视频中的水印如同微小的瑕疵&#xff0c;虽然旨在维护原创者的权益&#xff0c;却往往损害了内容的观感&#xff0c;降低了他人的分享欲望。那些恼人的水印&#xff0c;常常让人们束手无策。但别担心&#xff0c;接下来我将为你揭秘几种快…

羊大师讲解,羊奶怎么加热才不容易破坏营养

羊大师讲解&#xff0c;羊奶怎么加热才不容易破坏营养 随着人们对健康饮食的重视&#xff0c;越来越多的人开始选择羊奶作为补充营养的饮品。在加热羊奶的过程中&#xff0c;如果方法不当&#xff0c;很容易造成营养价值的损失。那么&#xff0c;如何加热羊奶才能最大程度地保…

gem5学习(7):内存系统中创建 SimObjects--Creating SimObjects in the memory system

目录 一、gem5 master and slave ports 二、Packets 三、Port interface 1、主设备发送请求时从设备忙 2、从设备发送响应时主设备忙 四、Simple memory object example 1、Declare the SimObject 2、Define the SimpleMemobj class 3、Define the SimpleMemobj class…

私域营销新趋势:电商品牌如何打破传统,实现共赢?

一、自私的私域 私域运营已经成为企业营销的重要手段之一&#xff0c;越来越多的品牌开始重视私域的构建和运营。瑞幸咖啡、熊猫不走和泡泡玛特等品牌的成功案例证明了私域运营的重要性和价值。这些品牌通过建立自己的用户社区&#xff0c;提供个性化的服务和营销策略&#xf…

ffmpeg 解码文件时的时间戳问题

实时流和普通文件 1 实时流 实时流编码时&#xff0c;我们一般不进行b帧编码&#xff0c;但是文件存储时为了减小大小&#xff0c;会增加b帧&#xff0c;实时流只带了I&#xff0c;P帧&#xff0c;那就会好很多 2 普通文件 很多文件带了b帧&#xff0c;所以要使用解码时间去同…

JavaScript(简写js)常用事件举例演示

目录 1.窗口事件onblur :失去焦点onfocus:获得焦点onload:窗口加载事件onresize:窗口大小缩放事件 二、表单事件oninput &#xff1a;当文本框内容改变时 &#xff0c;立即将改变内容 输出在控制台onchange&#xff1a; 内容改变事件onclick&#xff1a;鼠标单击时触发此事件 三…

Spring高手之路-SpringIOC

目录 何为IOC IOC的优点 Spring的IOC 补充 IOC是如何实现的&#xff1f; 何为IOC 所谓的IOC&#xff08;inversion of control&#xff09;&#xff0c;就是控制反转的意思。何为控制反转&#xff1f; 在传统的程序设计中&#xff0c;应用程序代码通常控制着对象的创建和管…

面试算法77:链表排序

题目 输入一个链表的头节点&#xff0c;请将该链表排序。 分析 归并排序的主要思想是将链表分成两个子链表&#xff0c;在对两个子链表排序后再将它们合并成一个排序的链表。 这里可以用快慢双指针的思路将链表分成两半。如果慢指针一次走一步&#xff0c;快指针一次走两步…

docker-compose部署zabbix服务

1.首先要有docker环境&#xff0c; 关闭防火墙&#xff0c;selinux 开启docker&#xff0c;并设置开机自启动 Linux的docker的安装https://blog.csdn.net/m0_58146415/article/details/134654933 2.docker-compose的安装----github下载 curl -SL https://github.com/docke…

JavaSE语法之十一:接口(超全!!!)

文章目录 1. 概念2. 语法规则3. 接口使用4. 接口特性5. 实现多个接口6. 接口间的继承7. 接口使用实例8. Clonable 接口和深拷贝9. 抽象类和接口的区别&#xff08;重要&#xff01;&#xff09; 1. 概念 在现实生活中的接口比比皆是&#xff0c;如&#xff1a;笔记本上的USB接…

批量抠图软件哪个好用?推荐这三款抠图工具给你

在数字图像处理的世界里&#xff0c;抠图是个不可或缺的环节。对于那些经常需要从复杂背景中提取主体的设计师和摄影师来说&#xff0c;抠图技巧无疑是一项宝贵的职业技能。然而&#xff0c;当面对大量的抠图需求时&#xff0c;手动处理不仅耗时&#xff0c;而且效率低下。因此…