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. cocos2d-x-3.0 window+eclipse Android Project 环境与开发新手教程

    今天闲来没事,听说最新cocos2d-x 出新版3.0.所以来学习一下. 大致參考官方教程:http://www.cocos2d-x.org/wiki/How_to_Build_an_Android_ ...

  2. Openstack(十三)部署管理服务horizon

    13.1horizon介绍 horizon是openstack的管理其他组件的图形显示和操作界面,通过API和其他服务进行通讯,如镜像服务.计算服务和网络服务等结合使用,horizon基于python ...

  3. POJ2186:Popular Cows(tarjan+缩点)

    题目解析: 这题题意没什么好说的,解法也挺简单的,只要会tarjan算法+只有一个出度为0的强连通分量题目有解这题就迎刃而解了. #include <iostream> #include ...

  4. ZOJ2588:Burning Bridges(无向连通图求割边)

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 吐下槽,不得不说ZOJ好坑,模版题做了一个多小时. 题意:*    ...

  5. 统计编程的框架与R语言统计分析基础——摘(2)统计分析之线性回归

    一.线性回归 1.简单线性回归 a. > x = women > x height weight 1 58 115 2 59 117 3 60 120 4 61 123 5 62 126 ...

  6. 如何把PDF文件转换为JPG图片

    大家有遇到需要将PDF文件转换为JPG的情况么,文档资料里面经常会有一些图片类型的内容,有的时候我们需要获取这些图片内容,但是PDF文件又是不可编辑的,那如何把PDF文件转换为JPG图片呢,跟着小编一 ...

  7. cocos进阶教程(5)CC_CALLBACK_X系列的使用技巧

    CC_CALLBACK_1,CC_CALLBACK_2,CC_CALLBACK_3 这些都是std::bind的宏,数字1,2,3主要表示要占位的数量,也是将来传递参数的数量. // new call ...

  8. ruby中的**

    在ruby中,**是乘方的意思.它是一个右结合性的运算.如下: 在多个乘方的时候,会先进行后面的乘方运算,结果作为指数再与前一位进行乘方运算.

  9. uwsgi手动安装时报错ValueError: invalid literal for int() with base 10: '32_1'

    安装uwsgi,安装步骤如下 wget https://projects.unbit.it/downloads/uwsgi-latest.tar.gz tar zxvf uwsgi-latest.ta ...

  10. showDoc的基本使用方法

    ShowDoc介绍 ShowDoc就是一个非常适合IT团队的在线文档分享工具,它可以加快团队之间沟通的效率. API文档( 查看Demo) 随着移动互联网的发展,BaaS(后端即服务)越来越流行.服务 ...