功能
judge 模塊主要從transfer中接收數據,並從HBS中獲取報警策略,然后進行閾值報警判斷
-
從HBS獲取報警策略
-
接收transfer 上報的數據,並存儲最新幾個點
-
判斷閾值,產生報警事件
-
判斷報警事件是否寫入redis
-
老舊報警數據的清理
配置文件
{
"debug": true,
"debugHost": "nil", #用於調適,在log中打印指定host的具體策略
"remain": 11, #指定內存中存放每個metric數據點的個數。11個表示內存中存放10個點
"http": {
"enabled": true,
"listen": "0.0.0.0:6081"
},
"rpc": {
"enabled": true,
"listen": "0.0.0.0:6080"
},
"hbs": {
"servers": ["127.0.0.1:6030"], # hbs最好放到lvs vip后面,所以此處最好配置為vip:port
"timeout": 300,
"interval": 60
},
"alarm": {
"enabled": true,
"minInterval": 300, # 連續兩個報警之間至少相隔的秒數,維持默認即可
"queuePattern": "event:p%v",
"redis": {
"dsn": "127.0.0.1:6379", # 與alarm、sender使用一個redis
"maxIdle": 5,
"connTimeout": 5000,
"readTimeout": 5000,
"writeTimeout": 5000
}
}
}
處理邏輯
策略同步
1.judge啟動之后會實例化RPC連接池,初始化RPCclient
- 向HBS請求監控策略,此時HBS返回的數據為
- strategy
{
"id": 228,
"result": {
"hostStrategies": [
{
"hostname": "open-falcon-1",
"strategies": [
{
"id": 5,
"metric": "load.1min",
"tags": {
},
"func": "all(#3)",
"operator": "\u003e",
"rightValue": 40,
"maxStep": 3,
"priorit
y": 0,
"note": "",
"tpl": {
"id": 3,
"name": "test",
"parentId": 1,
"actionId": 0,
"creator": "root"
}
}
]
},
{
"hostname": "open-falcon-2",
"strategies": [
{
"id": 4,
"metric": "proc.num",
"tags": {
"name": "mysql"
},
"func": "all(#3)",
"operator": "==",
"rightValue": 0,
"maxStep": 3,
"priority": 0,
"note": "",
"tpl": {
"id": 2,
"name": "com",
"parentId": 0,
"actionId": 3,
"creator": "root"
}
},
{
"id": 2,
"metric": "net.port.listen",
"tags": {
"port": "80"
},
"func
": "all(#3)",
"operator": "==",
"rightValue": 0,
"maxStep": 3,
"priority": 0,
"note": "",
"tpl": {
"id": 2,
"name": "com",
"parentId": 0,
"actionId": 3,
"creator": "root"
}
}
]
}
]
},
"error": null
}
- expression
{
"id": 229,
"result": {
"expressions": [
{
"id": 1,
"metric": "cpu.idle",
"tags": {
"module": "123"
},
"func": "all(#3)",
"operator": "==",
"rightValue": 0,
"maxStep": 3,
"priority": 0,
"note": "",
"actionId": 2
}
]
},
"error
": null
}
3.規整緩存策略。judge實現可以更加快速的進行閾值判斷,則需要在收到transfer數據之后盡快找到該數據對應的策略,所以對數據進行規整。分別用兩個大Map存放規整后的數據,strategy和expression
- strategy
key:endpoint/metric,value:[strategy1,strategy2,...]
- expression
key: metric/tag_k=tag_v.value: [strategy1,strategy2,...],如果多條tag,則會生成多個key
如 each(metric=qps,project=adv,module=nginx),規整后的數據為:
qps/project=adv
qps/module=nginx
歷史數據存儲
-
judge在啟動之后,首先會初始化一個historyBigmap。用於存放所有metric remain數量的數據
-
judge 接收transfer上報的數據。數據格式為
-
judge 根據endpoint、metric、sorted(tags) 計算md5值,然后組成一個map1 ,格式為:key:md5值,value:具體采集數據
-
最后將map1的數據存到historyBigmap中,此時 key 為 mao1 的key的前兩位即md5_v[0:2],value為[map1,map1map1..]
可見,最終在內存中存的數據為
bigmap: {md5[0:2]:[map1,map1]}
報警邏輯
報警條件
-
all(#3)/min(#3)/max(#3)/sum(#3)/avg(#3) 最新3個數據點所有/最小/最大/和/平均
-
diff(#3) 當前數據點減去最新的3個歷史點,拿到的差值,如果有任何一個超過閾值則告警
-
pdiff(#3) 當前數據點減去最新的3個歷史點,再除以歷史點,求得變動的波動率,如果任何一個波動率超過閾值則告警
判斷告警
1.judge收到數據並規整完之后,會試着在bigmap中找對應的key
2.判斷bigmap中的key對應的value是否有數據,有數據則追加,無數據則新建。此時還會做很多判斷,如數據合法性校驗、數據條數判斷等
-
根據endpoint+metric 找到內存中對用的strategy和expression,此時結果可能是一個列表,接下來會對tags進行匹配
-
循環strategy或expression的tags列表,判斷是否在數據的tags中,即如果策略里tags 是數據tags的子集,則該策略為該數據的告警策略
-
解析報警策略中的判斷函數
-
數據和閾值進行比較,如果觸發閾值,則產生一個告警事件
7.判斷告警事件是否放入alarm隊列,此時判斷規則為:
* 檢查的數據個數是否判斷條件(例如檢查最近5份數據,但是目前只有3份)
* 該策略是否被屏蔽(maxStep設置為0)
* 當前報警次數是否已經達到最大告警次數
* 距離上次報警是否滿足一定的時間間隔
注意:judge 對閾值判斷和告警 過程中,數據點不會重復用於和新數據點判斷。如
10:01 10:02 10:04 10:05 10:06 10:07 10:08 10:09 10:10 10:11 10:12 10:13
4 5 3 9 2 1 9 7 6 3 5 4
閾值:cpu.idle < 10,minInterval:120
發現 10次上報的數據都觸發了閾值,但是產生的告警時間點為:10:04,10:10
10:07由於和上次產生告警事件的間隔小於120s,所以不會產生告警事件
- 將告警事件根據告警的級別發送到alarm對應的level隊列
歷史臟數據清理
臟數據清理主要是為了清理那些很久沒上報的enpoint和metric,如果我們修改endpoint,那么會產生新的endpint,並上報,judge會重新存儲,這樣導致老的數據在內存中越來越多,最終造成內存溢出
-
http://127.0.0.1/count 查詢bigmap 中key 的數量
-
http://127.0.0.1:6081/strategy/{endpoint}/{metric} 查詢指定endpoint和metric 的strategy監控策略
-
http://127.0.0.1:6081/expression/{endpoint}/{metric} 查詢指定endpoint和metric 的expression監控策略
-
http://127.0.0.1:6081/history/{endpoint}/{counter} 清理長久未上報的數據