Fork me on GitHub

Sfiypig's notes

没有记录等于没有发生

本科毕业设计Ease-Monitor

Ease-Monitor是本人大学在毕业前尝试编写的一个分布式监控系统,目的是从开发的角度去了解一个监控系统的方方面面(实际上我只解决的一小部分问题-_-!),所以还是仅供学习使用

其主要包含了数据采集、数据转发、数据存储、异常判定及告警、数据可视化五个功能模块。其架构图如下:

Alt text

其后端完全使用Python实现,前端的数据可视化和平台管理基于Vue.js实现

后端项目地址

前端项目地址

项目组件

数据采集

Agent组件是监控系统的数据采集模块,目前其基于psutil采集了部分系统基础资源指标。在采集了系统资源之后,使用ZeroRPC上报给数据转发模块。目前Agent还处在雏形阶段,仅仅是数据采集…

数据采集模块的实现
数据采集模块整体实现了一个数据采集的客户端程序,Agent的整体结构和工作流程如图3-2所示。Agent启动后,其根据配置文件生成Sender和Psutil-Collector两个处理模块,Collector作为监控数据的生产者,其基于Psutil收集系统操作系统的一些运行状态信息,将采集到的信息写入内存队列,Sender通过ZeroRPC客户端进行指标的上报,消费Queue中的数据发送给数据转发组件。引入内存Queue的另一个好处是:当数据转发组件无法正常工作,或者Agent本地的网络故障等原因导致RPC调用失败后,内存Queue可最为监控数据的历史缓存,等系统恢复后重新对历史数据进行消费。

agent\_design(1)

Psutil库采集监控数据
Agent目前使用了第三方库进行指标数据的采集,使用Psutil库可以很大程度上减少底层劳动量,它提供了跨平台的解决方案。使用Psutil提供的接口可以轻易的获得系统的状态信息,如表3-1是一些常用的API示例。

表 3.1 Psutil API常用实例

CPU 内存 disk 网络设备 传感器
API cpu_times virtual_memory disk_usage net_io_counters sensors
结果 各类进程占用CPU百分比 buffer/cache/used/free等使用量(byte) 磁盘设备使用情况,如byte数 网络设备的发送、接受字节数、错误的字节数 系统的传感器的温度

使用Zero-RPC上报数据
Zero-RPC是一个轻量级、可靠的、跨语言的第三方RPC库,其常被用作系统端到端的分布式通信,其内置了heartbeat心跳、超时保护等功能。Zero-RPC提供了Python的client/server端的编程接口,使用Zero-RPC构建一个客户端如下图所示,其会创建一个Zero-RPC的客户端,客户端会连接到配置文件设置的主机地址和主机端口。

数据转发组件提供了ZeroRPC的服务端接口和一个通用的HTTP接口,数据转发组件在收到上报的指标后会对数据的格式进行简单的检查。只要上报的数据符合格式,就会按照其配置文件中的配置规则进行转发。数据格式如下:

1
2
3
4
5
6
7
8
9
10
11
{
"value": 0,
"timestamp": 1528557126,
"counterType": "GAUGE",
"step": 60,
"metrics": "cpu.nice.percent",
"tags": {
"host_ip": "182.254.155.58",
"hostname": "sh.zhxfei.com"
}
}

数据转发

transfer收到数据后,会对unpack的数据进行格式检查,通过后会将数据写入一个定长的内存队列,这个队列会被指定数量的greenlet监听并消费,greenlet会将数据向后端转发, 一般其会将每个指标数据转发到后端的异常判定和数据存储两个模块。

目前数据转发组件为异常判定和数据存储组件各自维护了一份redis列表,其会不断得LPUSH监控数据到后端去。

数据存储

storage主要是数据的写入, 其主要是从redis队列中pull到一定条目的数据然后写入Mongodb,其目前只支持Mongo一种数据存储形式。

MongoDB Sharding集群
Ease-Monitor使用了MongoDB进行数据存储。MongoDB是一个灵活、可扩展、支持索引的分布式文档型数据库,和传统的关系型数据库MySQL类似,其支持插件式存储引擎,其中Wired-Trigger存储引擎支持事务,和传统的MySQL不同,MongoDB没有严格的数据范式,且MongoDB的特殊的document(文档)类型对JSON格式的数据原生进行了很好的优化,MongoDB是现在最流行的NoSQL之一。

Ease-Monitor支持复制集合和分片两种集群模式,复制集合借鉴了MySQL中的复制架构,MongoDB复制集合可部署一主多从的模式,其中Master服务器负责数据的写请求,Slave服务器是Master服务器的复制备份,只响应读请求。Sharding集群是复制集合的功能扩充版本,其可以根据插入数据的key进行Hash或Range计算,将插入的数据根据索引规则分散到后端的复制集中,对于数据的读写请求,MongoDB分片集群中会有内一个特殊的叫做Mongos的复制集进行数据路由,Mongos维护了分片集合中的所有复制集合的数据。

如图展示了数据存储模块结合MongoDB 分片集群存储监控数据的流程。

Mongo(2)

数据存储模块首先会从Redis缓存队列中拉取实时的监控数据,Range是由Mongos维护的一个根据key的维护的线性区间,这个区间会根据Mongo复制集的数量均分成N段,对于每条监控数据,都会根据其tags和metrics进行Range计算,并将监控数据映射到后端的复制集中,Mongos根据规则将数据存储模块的Mongo Client重定向,数据存储模块会将数据写入到符合规则的复制集。

为了增加数据均衡的粒度,实际上Mongo分片集群中有chunk的概念,每个chunk的大小是固定的,也是数据经过Range计算中映射的最小单元,每个复制集合都会被映射N个chunk。若chunk的数量在复制集之间不均匀,Mongos会启动balance线程将数据以chunk为单元进行迁移。
MongoDB 索引优化
根据Ease-Monitor监控数据的特点:

  1. 时间戳是一个持续递增的Integer。
  2. tag和metrics可以锁定到指标类型、指标的源机器。

我们在插入数据的时候可以实现将数据均衡写入到所有的Mongo分片集群中的复制集中,在读取某个机器的某个指标的时候,可以只在一个复制结合中读数据,对于这种固定值加时间戳的特点来说,适合对存储集合开启复合索引。

具体操作如图所示。其针对easy_monitor中的monitor_60数据库开启了分片功能,并选择tags和timestamp作为符合索引的复合key,类型为Range。

选区\_112

异常判定和告警

异常判定Watcher根据管理员配置的异常策略表达式对监控数据进行检查,对于判定出异常数据产生异常事件发送给告警模块,告警模块alert对异常事件进行处理,根据管理员配置的告警策略进行收敛告警。

异常判定和告警模块
异常判定Watcher根据管理员配置的异常策略表达式对监控数据进行检查,对于判定出异常数据产生异常事件发送给告警模块,告警模块alert对异常事件进行处理,根据管理员配置的告警策略进行收敛告警。

异常判定组件的实现细节如图所示,其在启动时会首先启动三个Greenlet,第一个Greenlet会定时和API Server同步异常判定策略,并为其维护一个异常判定策略池,称为Judge Item Pool,第二个Greenlet会一直从Redis中拉取监控数据,并将key不在Judge Item Pool中的监控数据给过滤掉,并使用过滤后的数据更新历史数据缓存,再通过Gevent Queue发送给最后一个Greenlet,这个Greenlet会将Queue中的数据取出,并从对应的策略池中取出对应的Judge Item,并再生成一个Greenlet进行异常判定的逻辑执行。新的Greenlet会将根据对应的历史数据缓存和异常判定表达式进行判定。若在历史数据缓存中的N个数据点中有异常事件产生,则产生judge event,发送给报警队列,告警模块从告警队列中取出事件消费。

Untitled Diagram(11)

异常判定数据模型
异常判定的数据模型如图所描述,其主要包含了四个字段,其中 选区\_114

图3.11 异常判定数据模型

condition是异常判定表达式,judge_item_cache是Judge Item的缓存池,每次创建异常策略实例时,都会优先从缓存中获取。

异常判定效果通常表现为:当一种类型监控指标的value在一定的时间窗口之内,都满足大于或小于某个阈值,则判定为指标异常。如异常判定表达式表现为:all#3#gt#20,表示若检测到与对应policy绑定的指标连续3次大于阈值20,则产生一个告警事件。其中all表示连续的意思,在此处我将其定义为异常判定函数,表格3.3列举目前的异常判定函数及其含义:

异常判定函数 含义
all 连续n次
max 取n次中value最大的item
min 取n次value中最小的item
avg n次中value的均值
diff n次中的value取一次差分计算的结果,再取函数all

其中diff经常用在bit/s、byte/s之类有着速率含义的比较。‘gt’是比较函数,表3.4阐明了了四种比较函数及其含义。

比较函数 含义
gt great than,大于
gte great than and equal,大于等于
lt less than,小于
lte less than and equal,小于等于

历史数据点缓存实现
异常判定组件需要一直根据策略将历史数据和策略表达式中的阈值进行比较,为了保证异常判定组件可以高效获得历史数据,异常判定组件需要在内存中生成历史数据点缓存,并支持每次获取以时间排序最近的N次历史数据,Ease-Monitor使用基于时间戳大小的最小堆实现。

Ease-Monitor根据metrics和tags区分指标类型,并为每种设置了异常判定策略的指标维护一个列表,其列表使用最小堆实现根据时间戳排序,在获取最近N次的时候,直接从堆上获取最大的N个数据,所有的列表会放入一个哈希表中,以metrics和tags的哈希值作为key。

Python的heapq模块提供了堆队列算法的实现,堆是一种特殊的二叉树,每个父节点的值小于其任何子节点的值,下图描述了堆列表具体的应用。

选区\_115

可视化和平台管理

数据可视化组件使用了较为新颖的MVVM的设计模式,前端使用Vue.JS,后端使用了flask_restful

其主要是为Ease-Monitor提供了监控数据的可视化、策略配置、用户管理、登录验证等功能,前后端通过http进行交互。

部署

目前的想法是基于docker-compose,待功能完善再更新….

效果

用户登录和权限验证

数据可视化组件提供了权限验证和用户登录的功能,对于没有登录过的用户前端路由会将其重定向到登录页面,当用户输入账号和用户名密码后,前端路由会向后端的Rest API发起token请求,账号和密码验证通过后,后端回复token并被前端路由保存到vuex中,并保存到cookie,每次向请求后端资源会携带token,后端根据token对用户身份进行辨别。

数据报表模块

数据报表模块是对采集上报的监控数据进行展示的组件,其主要提供了机器指标预览(overview)、历史数据查询、指标对比三个子功能。

(1)机器指标预览

机器指标预览是以机器为维度,从此页面可对机器的运行状态进行直观的描述,具体如图4.2所示,其中包含系统的平均负载、TCP套接字连接状态数量、CPU状态、内存使用明细、网卡实时速率、文件系统使用百分比等等。

机器指标语言只支持六小时内的历史数据展示。

monitor - Google Chrome\_121

图4.2 机器指标预览页面

(2) 历史数据查询

历史数据查询子功能对系统管理元提供了查询历史所有上报的监控数据的功能。如图4.3所示,其支持机器、指标、和任意时间维度的切换。从图4.3可看出,该机器在近六小时内运行稳定,负载较低,在下午八点十六分负载略高。

2018-05-28 20-29-17屏幕截图

图4.3 机器指标预览页面

(3) 指标对比

机器指标对比子功能提供了不同机器之间的相同指标对比的功能。如图4.4展示了所选的两台机器上TCP套接字处于TIME_WAIT状态的数量对比,可间接看出,主机名为*22*的机器网络连接上相对另一台机器较为繁忙。

图4.4 机器指标预览页面

告警管理模块

告警管理组件提供了以用户为维度对异常判定策略和告警策略的逻辑管理。为了增加异常判定策略复用程度,一条异常判定策略称之为Strategy,一条告警策略称为Alerter,而一条Policy是多条Strategy和多条Alerter的的逻辑关联。 Strategy描述了和监控指标数据模型对应的抽象,如metrics,condition,指标等级等,而Alerter描述了告警数据对应的抽象,如发送给的告警人列表,告警类型,收敛时间等等。而Policy可实现绑定Strategy和Alerter,并增加tags,以tags来对数据的发送者进行区分匹配。

图4.5、图4.6、图4.7分别展示了Ease-Monitor上对Strategy、Alerter、Policy的展示、增加、编辑、删除等操作,告警管理模块前端页面具有很多人性化设计,如表单编辑预填充、表单验证、根据HTTP response状态进行消息闪现等。

2018-05-28 20-54-28屏幕截图

图4.4 Strategy操作页面

2018-05-28 21-04-39屏幕截图

图4.6 Alerter操作页面

2018-05-28 21-04-32屏幕截图

图4.7 Policy操作页面

Admin模块

Admin模块包含了监控系统的用户和数据管理功能。

用户管理指可以对监控系统的中用户的信息进行添加、修改、删除等操作,用户管理页面如图4.8所示,新增的用户可登录到Ease-Monitor进行查看报表,策略配置等,并且若Alerter设置告警类型为email,则会使用用户管理模块设置的邮箱地址。

2018-05-28 21-15-48屏幕截图

图4.8 用户管理页面

数据管理是对监控数据中的历史数据进行管理,因为并不是所有的历史数据都有使用价值,可针对部分时间过久、指标等级较低的历史数据进行删除等,减小后端数据库的容量。

告警信息发送

在异常判定和告警组件会通过邮件形式提醒管理员。如图4.9所示为告警内容。

alert1

图4.9 告警邮件内容

Ease-Monitor为了人性化告警,实现了告警收敛功能,如图4.10展示了在收敛时间为300秒的时候,管理员邮件接收情况。

alert

Comments