openfalcon源码分析之Judge
openfalcon源码分析之Judge
本节内容
- Judge功能
- 源码分析
- 设计优缺点
1. Judge功能
在open-falcon中,Judge模块的功能是通过从HBS上同步告警的strategys(告警策略),及Expression,用来在接收transfer上报过来的数据时,对数据进行检测,每收到一条上报的数据,就去匹配对应的strategy和Expression是否满足条件,判断是否需要向redis发送告警。
告警策略
open-falcon中的策略有两类,strategys和Expression。strategys与主机进行管线,可以通过一个主机找到其对应的所有strategys。而Expression则不需要有任何关联,是对全局范围内进行的一个过滤和判断。
stratrgys查找策略
从transfer上接收过来的数据带有endpoint,通过主机可以找到其对应的主机组(主机和主机组是多对多的关系),通过主机组可以找到对应的模板组(模板和主机组是多对多的关系),模板之间又可能有继承关系,通过模板组可以找到对应的strategy(模板和strategy是一对多的关系)一个模板就是一组strategy的集合。这样就可以通过上报过来的数据的endpoint找到其对应的所有的strategys了。
expression查找策略
expression不和主机关联,其针对的是全局的配置,主要对应一些需要特殊定制的告警检查。
2. 源码分析
处理流程分析
接收数据方
- 通过RPC注册两个方法,一个是ping,返回一个nil的返回值,另一个是send,处理transfer发送过来的数据。
- 对于transfer发送过来的每个监控数据,都会生成一个pk(对数据的endpoint,metric,tags进行字符串拼接,之后再用md5进行hash,生成一个hash值)。通过pk的前两位hash值,去HistoryBigMap中找到对应的值,调用PushFrontAndMaintain。(HistoryBigMap的结构会在后面进行讲解)
- 调用PushFrontAndMaintain会去JudgeItemMap中找到pk对应的值(链表)
若该pk能找到值,则调用该链表的PushFrontAndMaintain方法,将新到来的监控数据和链表最大长度传递进去。链表的PushFrontAndMaintain方法将新监控数据插入到链表的头部,如果超过了最大长度,则把最老的数据删除。再调用Judge方法对新监控数据和历史数据进行判断。
- 若没找到值,则会新创建一个链表,把新监控数据放入链表中。再调用Judge方法对新监控数据和历史数据进行判断。
- Judge方法会调用CheckStrategy方法以及CheckExpression方法对新监控数据和历史数据进行处理。
- CheckStrategy方法先将监控数据中的endpoint和metric进行字符串拼接成key,通过key去strategys中寻找对应的strategys列表。对于一个监控数据如果找到了多个strategy,则会对每个strategy的tags进行匹配,若和监控数据不符合则被过滤掉。剩下的每个strategys将会调用judgeItemWithStrategy方法,该方法先将strategy的表达式进行拼接找到对应的函数,然后将历史数据传递到Compute中进行逻辑判断,如果判断匹配则返回的值isTriggered为true,否则返回false.在judgeItemWithStrategy中会创建event事件,调用sendEventIfNeed方法判断该event是否应该发送出去。
- sendEventIfNeed方法会去检查LastEvents中该event是否已经存在,并按照一定规则判断是否需要调用sendEvent将event发送到redis中。源码如下.
- CheckExpression方法先将监控数据中的endpoint、metric、tags进行字符串拼接成key,再用该key在ExpressionMap字典中检查是否有对应的expressions,如果找到则调用filterRelatedExpressions进行处理
- filterRelatedExpressions检查所有对应的expressions,筛选掉tags不匹配的expressions,剩下的就是所有符合条件的expressions,针对所有符合条件的expressions,调用judgeItemWithExpression构建告警event,后面的处理步骤和strategys一致。
- CheckStrategy方法先将监控数据中的endpoint和metric进行字符串拼接成key,通过key去strategys中寻找对应的strategys列表。对于一个监控数据如果找到了多个strategy,则会对每个strategy的tags进行匹配,若和监控数据不符合则被过滤掉。剩下的每个strategys将会调用judgeItemWithStrategy方法,该方法先将strategy的表达式进行拼接找到对应的函数,然后将历史数据传递到Compute中进行逻辑判断,如果判断匹配则返回的值isTriggered为true,否则返回false.在judgeItemWithStrategy中会创建event事件,调用sendEventIfNeed方法判断该event是否应该发送出去。
// sendEventIfNeed方法中判断event是否该发告警的逻辑
if isTriggered {
event.Status = "PROBLEM"
if !exists || lastEvent.Status[0] == 'O' {
// 本次触发了阈值,之前又没报过警,得产生一个报警Event
event.CurrentStep = 1
// 但是有些用户把最大报警次数配置成了0,相当于屏蔽了,要检查一下
if maxStep == 0 {
return
}
sendEvent(event)
return
}
// 逻辑走到这里,说明之前Event是PROBLEM状态
if lastEvent.CurrentStep >= maxStep {
// 报警次数已经足够多,到达了最多报警次数了,不再报警
return
}
if historyData[len(historyData)-1].Timestamp <= lastEvent.EventTime {
// 产生过报警的点,就不能再使用来判断了,否则容易出现一分钟报一次的情况
// 只需要拿最后一个historyData来做判断即可,因为它的时间最老
return
}
if now-lastEvent.EventTime < g.Config().Alarm.MinInterval {
// 报警不能太频繁,两次报警之间至少要间隔MinInterval秒,否则就不能报警
return
}
event.CurrentStep = lastEvent.CurrentStep + 1
sendEvent(event)
} else {
// 如果LastEvent是Problem,报OK,否则啥都不做
if exists && lastEvent.Status[0] == 'P' {
event.Status = "OK"
event.CurrentStep = 1
sendEvent(event)
}
}
同步strategy和expressions方
main函数中起了go-routine 专门用来从hbs同步strategy和expressions,同步完之后重新组装成StrategyMap和ExpressionMap两个字典。
几个数据结构分析
- HistoryBigMap
- HistoryBigMap是个大字典,key是pk的hash值的前两位,一共有16*16=256个键,value是NewJudgeItemMap,也是一个字典,该字典的key是pk,value对应历史数据组成的链表,链表最大长度可在配置文件中的remain配置,默认是11,也就是默认对每个数据,保留11个历史数据节点。
- StrategyMap
- StrategyMap是个字典,key是hostname和Metric拼接的字符串,value是一个array,因为同一个hostname和Metric可能对应多个Strategy(可能tags不同,当然可能没有tags时,父子模板中都有该Strategy)
- ExpressionMap
- ExpressionMap是个字典,key是metric和tags拼接的字符串,value是一个array,metric和tags无法唯一确定expression。
- LastEvents
- LastEvents是个字典,key是event.Id,该id是由strategy.id和pk的hash值拼接产生的,可以唯一确定一个数据,所以value就是event事件本身。
3. 设计优缺点
优点:
- 支持告警间隔以及最大告警次数,太多的告警并没有什么帮助,况且会将真正有用的告警淹没在无意义的告警中。
- 支持Expression,zabbix是将告警和主机绑定起来,某些并不和某个主机关联的告警无法做,有了Expression之后就可以关联那一类告警了。
缺点:
- 只支持按照次数告警,如果支持按照时间告警就好了,比如某台机器连续五分钟cpu负载过高告警。
openfalcon源码分析之Judge的更多相关文章
- openfalcon源码分析之hbs
openfalcon源码分析之hbs 本节内容 hbs功能 hbs源码分析 hbs设计优劣 1. hbs功能 hbs在整个open-falcon项目中承担的角色就是连接数据库,作为数据库缓存,缓存配置 ...
- openfalcon源码分析之graph
openfalcon源码分析之graph 本节内容 graph功能 graph源码分析 2.1 graph中重要的数据结构 2.2 graph的简要流程图 2.3 graph处理数据过程 2.4 gr ...
- openfalcon源码分析之transfer
本节内容 transfer功能 transfer接收数据来源 transfer数据去向 transfer的一致性hash transfer的一致性hash key的计算 transfer源码分析 2. ...
- openfalcon源码分析之agent
本节内容 agent功能 1.1 agent上报数据 1.2 agent与HBS同步 1.3 agent Http服务 agent源码分析 2.1 初始化config配置 2.2 初始化根目录,本地I ...
- 8.源码分析---从设计模式中看SOFARPC中的EventBus?
我们在前面分析客户端引用的时候会看到如下这段代码: // 产生开始调用事件 if (EventBus.isEnable(ClientStartInvokeEvent.class)) { EventBu ...
- 9.源码分析---SOFARPC是如何实现故障剔除的?
SOFARPC源码解析系列: 1. 源码分析---SOFARPC可扩展的机制SPI 2. 源码分析---SOFARPC客户端服务引用 3. 源码分析---SOFARPC客户端服务调用 4. 源码分析- ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
随机推荐
- dp\dpi\px\pt\em单位长度理解
屏幕都有固定的物理长宽度属性和分辨率 比如电脑.比如手机屏幕 例如有手机屏幕尺寸是1.5英寸x2英寸,屏幕分辨率为240x320, 那么可以推算水平方向每英寸的像素数(dpi)是:240/1.5=16 ...
- ubuntu常用操作命令以及它的通道模式简解
1.tail tail -f filename :可以动态查看文件的写入,按ctrl+c结束查看. 要显示 notes 文件的最后十行,输入: tail -n -10 notes tail notes ...
- MegaCli 监控raid状态
MegaCli 监控raid状态 http://blog.chinaunix.net/uid-25135004-id-3139293.html 简介 MegaCli是一款管理维护硬件RAID软件,可以 ...
- expdp&impdp备份恢复常用命令
备份前准备 创建备份用户 create user backup identified by backup#2018 ; 授予导入导出角色 grant connect,resource to backu ...
- Amber安装并行
现在简单介绍一下amber12中安装openmpi并行的过程. 1. 下载openmpi版本在1.5-1.9之间的(openmpi-1.6.5.tar.bz2) 这是因为$AMBERHOME/Ambe ...
- 爬取51job职位信息之编码问题
兴趣来潮,爬了下51job,但是遇到编码问题!以下是简单的一段代码 获取整个页面数据 # -*- coding:utf-8 -*- import requests import sysreload(s ...
- Django组件拾忆
知识预览 一 Django的form组件 二 Django的model form组件 三 Django的缓存机制 四 Django的信号 五 Django的序列化 回到顶部 一 Django的form ...
- vuex的一个坑
1 error in callback for watcher "function (){ return this._data.$$state }" 用深拷贝解决 2 接口依赖: ...
- 120. Triangle(动态规划 三角形最小路径 难 想)
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...
- javascript模式(1)--私有成员
javascript是基于对象的一门语言,没有想java等语言那样子拥有封装的特性.但是javascript可以通过闭包来进行模拟. 1.构造函数与私有成员 可以用构造函数形成一个闭包,实现内部成员的 ...