设计一个监控模块

1、监控模块设计

       要在开发平台层设计一个监控模块,提供平台级监控能力。几乎所有的监控系统都基于 CS 模式设计,监控模块也基于 CS 模式。但是开发平台层不需要自己完全实现完整的 Server 端和 Client 端。就这样设计了第一版监控模块。

第一版监控模块

  • server 端几乎无需自己实现,Client 只需要能以主动推送或者暴露接口的形式将监控数据提交至 server 端并展示即可。

  • client 端在逻辑上划分三层:数据源、采集层、接口层;

  • 数据层是指被采集对象的整体,监控数据源自于这里。监控数据可以是业务数据,可以是开发平台层数据,例如 rpc 调用信息,还可以直接是应用环境三方的,任何可以被应用程序获取的信息,例如:Spring Boot Actuator。

  • 采集层是真正需要开发平台层实现的逻辑,需要采集的各项指标待定.

  • 接口层负责将数据交付给展示层。

       UML 设计如下:

UML

2、为何 Server 端不采用 Spring Boot Admin

       Spring Boot Actuator + Spring Boot Admin 是 Spring 官方标配。但是 Spring Boot Admin 生产部署作为监控平台的很少见,并且 Spring Boot Admin 由于在数据交互上没有统一的数据规范,展示层必须针对特定数据进行前端开发(重新开发spring-boot-admin-server-ui )。目前 Spring Boot Admin 能展示的数据主要是 JVM 的进程信息以及依赖于 Spring 环境的相关信息(环境配置、beans、web)。

Spring Boot Admin

3、各层的理想组合

       micrometer 的数据结构与普罗米修斯数据结构设计上一致,生产环境的监控平台 prometheus + grafana 几乎是最常见的,Sping Boot Actuator 对 prometheus 已经天然支持(spring-boot-actuator-autoconfigure @org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration)。因此将 Sping Boot Actuator 的 prometheus 端点作为接口层,将 prometheus + grafana 作为 Server 端,micrometer 作为采集层的采集工具,是最理想的组合。可行性验证效果展示:

prometheus + grafana

4、定制化监控系统的引入

       因为引入了一体化监控平台 XXX,开发平台要考虑将 XXX 作为 Server 端。Xxx 将监控信息抽象为 XxxBean 对象,并通过派生 XxxBean 对象得到三种监控场景。设计方案如图所示:

Xxx 设计

       除了支持上报 XxxBean 监控对象,Xxx 还支持基于日志的交易监控:

Xxx 设计

       其中需要特别说明:1)业务系统接入 Xxx 上报监控的能力,必须在业务逻辑中组装 XxxBean 模型(可用性模型、事件模型、调度模型);2)基于日志的交易监控,必须调整应用系统的日志输出格式。

5、基于度量指标的通用监控设计思路

       Xxx 从使用场景出发设计了监控平台,开发平台需要考虑更加通用开放的监控标准,基于开发的监控标准设计监控能力,再进一步将通用的监控能力运用于具体场景。

       在信息技术中,监控指的是对系统、网络、应用程序、基础设施等的持续观察、测量和分析,以确保其正常运行、性能优化和安全性。让我们回到监控这件事情本身来考虑,能否基于 V1 方案中 prometheus 协议进行设计,形成通用开发的监控能力,以应对类似于一体化监控平台等诸多展示层的接入需求。

       假设系统生成有度量指指标:demo_cpu_usage、demo_mem_usage、demo_transfer_amount。分别记作 a、b、c。

1
2
3
4
5
6
7
8
9
10
11
# prometheus 协议数据
<metric_name>{<label_name>=<label_value>, ...} <value> <timestamp>

a:
demo_cpu_usage{target="192.168.1.2"} 81 1694116786000

b:
demo_mem_uasge{target="192.168.1.2"} 81 1694116786000

c:
demo_transfer_amount{vip_user="000000123"} 20000000 1694116786000

       另外设:

       bool = g(x):x.value 必须小于 80,否则 g 函数返回 false。

       float = f(x):当 x.tag.vip_user in vip_user_list,x.value 如果大于一百万,f 则返回 x.value。

       以上 g 函数和 f 函数目的是分别通用的程序监控场景和业务场景,可以根据实际需要定义出更加复杂灵活的函数法则,函数法则施加于若干监控指标,从而得到一个具体的监控场景。以 g 函数和 f 函数为例:

       场景一:当 cpu 或者 mem 内存低于 80 的时候,触发可用性监控,伪代码如下:

1
2
3
if g(a) || g(b) 
# 组装可用性 XxxBean 模型
endif

       场景二:当 VIP 用户转账金额超过 100 万时,触发事件监控,伪代码如下:

1
2
3
if  f(c) > 1000000
# 组装事件 XxxBean 模型
endif

       基于以上具体案例的分析可以看出,监控模型的上报场景,完全是可以从一些自定义的监控指标中得出的,因此基于 prometheus 协议监控度量指标的封装,可以当做一种通用监控能力。基于这种能力,也可以很方便对交易进行监控,不仅是基于 Xxx 模型地监控,还是基于 prometheus 协议的监控,都有能力做到,此不赘述。

6、监控优化方案

       对 V1 方案优化如下:

       1)采集层基于 prometheus 协议设计出度量指标公共服务 MetricsService;

       2)在接口层引入度量指标汇聚层,用于汇聚各项指标数据,根据展示层实际的接入方式进行转换。

监控优化方案

7、知识补充一:prometheus

       Prometheus 是一个开源的监控系统,可以看做是一个时序数据库,它使用一种特定的数据格式来收集和存储时间序列数据。数据类型:

  • Counter(计数器):一个单调递增的度量值,通常用于记录事件发生的次数。例如, HTTP 请求的计数。

  • Gauge(量表):一个可以任意增减的度量值,通常用于记录某一时刻的状态或值。例如,当前的内存使用量、CPU 使用率等。

  • Histogram(直方图):用于测量样本的分布情况,比如请求延迟。它将数据样本划分到不同的桶(buckets)中,并记录每个桶中的样本数量。

  • Summary(摘要):类似于直方图,但会额外提供请求的总数和总和,通常用于计算百分位数等聚合度量。

       数据格式:

1
<metric_name>{<label_name>=<label_value>, ...} <value> <timestamp>
  • metric_name: 度量名称,必须符合正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]*,例如:http_requests_total。

  • {<label_name>=<label_value>, …}: 可选的标签部分,用来区分不同的时间序列,例如:{method=“GET”, endpoint="/api"}。

  • value: 度量的值,是一个浮点数。

  • timestamp: 可选的 UNIX 时间戳,以毫秒为单位。

       数据样例:

1
2
3
4
# HELP http_requests_total Total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="GET", handler="/home"} 1027 1694116786000
http_requests_total{method="POST", handler="/api"} 521 1694116786000

8、知识补充二:采集工具比较

采集工具比较

打赏
  • Copyrights © 2017 - 2025 杨海波
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信