openfalcon源码分析之Judge

本节内容

  1. Judge功能
  2. 源码分析
  3. 设计优缺点

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. 源码分析

处理流程分析

接收数据方

  1. 通过RPC注册两个方法,一个是ping,返回一个nil的返回值,另一个是send,处理transfer发送过来的数据。
  2. 对于transfer发送过来的每个监控数据,都会生成一个pk(对数据的endpoint,metric,tags进行字符串拼接,之后再用md5进行hash,生成一个hash值)。通过pk的前两位hash值,去HistoryBigMap中找到对应的值,调用PushFrontAndMaintain。(HistoryBigMap的结构会在后面进行讲解)
  3. 调用PushFrontAndMaintain会去JudgeItemMap中找到pk对应的值(链表)
    • 若该pk能找到值,则调用该链表的PushFrontAndMaintain方法,将新到来的监控数据和链表最大长度传递进去。链表的PushFrontAndMaintain方法将新监控数据插入到链表的头部,如果超过了最大长度,则把最老的数据删除。再调用Judge方法对新监控数据和历史数据进行判断。

    • 若没找到值,则会新创建一个链表,把新监控数据放入链表中。再调用Judge方法对新监控数据和历史数据进行判断。
  4. 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一致。
// 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两个字典。

几个数据结构分析

  1. HistoryBigMap

    • HistoryBigMap是个大字典,key是pk的hash值的前两位,一共有16*16=256个键,value是NewJudgeItemMap,也是一个字典,该字典的key是pk,value对应历史数据组成的链表,链表最大长度可在配置文件中的remain配置,默认是11,也就是默认对每个数据,保留11个历史数据节点。
  2. StrategyMap
    • StrategyMap是个字典,key是hostname和Metric拼接的字符串,value是一个array,因为同一个hostname和Metric可能对应多个Strategy(可能tags不同,当然可能没有tags时,父子模板中都有该Strategy)
  3. ExpressionMap
    • ExpressionMap是个字典,key是metric和tags拼接的字符串,value是一个array,metric和tags无法唯一确定expression。
  4. LastEvents
    • LastEvents是个字典,key是event.Id,该id是由strategy.id和pk的hash值拼接产生的,可以唯一确定一个数据,所以value就是event事件本身。

3. 设计优缺点

优点:

  1. 支持告警间隔以及最大告警次数,太多的告警并没有什么帮助,况且会将真正有用的告警淹没在无意义的告警中。
  2. 支持Expression,zabbix是将告警和主机绑定起来,某些并不和某个主机关联的告警无法做,有了Expression之后就可以关联那一类告警了。

缺点:

  1. 只支持按照次数告警,如果支持按照时间告警就好了,比如某台机器连续五分钟cpu负载过高告警。
 
 
 

openfalcon源码分析之Judge的更多相关文章

  1. openfalcon源码分析之hbs

    openfalcon源码分析之hbs 本节内容 hbs功能 hbs源码分析 hbs设计优劣 1. hbs功能 hbs在整个open-falcon项目中承担的角色就是连接数据库,作为数据库缓存,缓存配置 ...

  2. openfalcon源码分析之graph

    openfalcon源码分析之graph 本节内容 graph功能 graph源码分析 2.1 graph中重要的数据结构 2.2 graph的简要流程图 2.3 graph处理数据过程 2.4 gr ...

  3. openfalcon源码分析之transfer

    本节内容 transfer功能 transfer接收数据来源 transfer数据去向 transfer的一致性hash transfer的一致性hash key的计算 transfer源码分析 2. ...

  4. openfalcon源码分析之agent

    本节内容 agent功能 1.1 agent上报数据 1.2 agent与HBS同步 1.3 agent Http服务 agent源码分析 2.1 初始化config配置 2.2 初始化根目录,本地I ...

  5. 8.源码分析---从设计模式中看SOFARPC中的EventBus?

    我们在前面分析客户端引用的时候会看到如下这段代码: // 产生开始调用事件 if (EventBus.isEnable(ClientStartInvokeEvent.class)) { EventBu ...

  6. 9.源码分析---SOFARPC是如何实现故障剔除的?

    SOFARPC源码解析系列: 1. 源码分析---SOFARPC可扩展的机制SPI 2. 源码分析---SOFARPC客户端服务引用 3. 源码分析---SOFARPC客户端服务调用 4. 源码分析- ...

  7. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  8. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  9. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

随机推荐

  1. 【Python】sasa版:文件中csv读取在写入csv读取的数据和执行是否成功。

    sasa写的文件(包含解析文字) # coding=utf- from selenium import webdriver from time import sleep import keyword ...

  2. 提高myEclipse的开发效率和外观,这些你都设置了吗?

    [前言] 为什么我的myeclipse开启速度那么慢,为什么别人能哗啦啦几个快捷键打出一片代码?刚开始使用myeclipse的时候,相信大家都有这个疑问,慢慢的,也懂得一些配置,我也不例外,在此,把常 ...

  3. 不登录到MySQL执行SQL语句

    mysql -e 不登录到MySQL执行SQL语句 mysql -u root -p -e "SHOW DATABASES"

  4. IOS #ifdef 的那些事儿

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u012884714/article/details/25188685 格式有点乱,整了几次都整只是来 ...

  5. Nodepad++ 资料整理

    http://www.crifan.com/files/doc/docbook/rec_soft_npp/release/webhelp/use_sbracket_lite_autocomplete_ ...

  6. SCons构建工具使用

    scons是一个Python写的自动化构建工具,和GNU make相比优点明显:    1. 移植性:python能运行的地方,就能运行scons    2. 扩展性:理论上scons只是提供了pyt ...

  7. Linux /proc/pid目录下各文件含义

    /proc 是一个伪文件系统, 被用作内核数据结构的接口, 而不仅仅是解释说明/dev/kmem. /proc 里的大多数文件都是只读的, 但也可以通过写一些文件来改变内核变量. ( Linux 内核 ...

  8. 前端基础(CSS)

    CSS 语法 .clearfix:after{ content: ""; display: block; clear: both; } 解决 float 块之后的塌陷(后面增加了一 ...

  9. 2017ACM/ICPC Guangxi Invitational Solution

    A: A Math Problem 题意:给出一个n,找出有多少个k满足kk  <= n 思路: kk的增长很快,当k == 16 的时候就已经超过1e18 了,对于每一次询问,暴力一下就可以 ...

  10. Android 自定义View-字母索引表(一)

    在有些Android应用中,为了方便快速定位,经常会看到屏幕右侧有一个字母索引表,今天尝试使用自定义View的方式实现了索引表的基本布局. 字母索引表的样式如下面的示意图所示, 此时我们至少需要知道以 ...