基于Alertmanager設(shè)計告警降噪系統(tǒng),成本低可落地
一、背景
轉(zhuǎn)轉(zhuǎn)基于Prometheus落地了一體化監(jiān)控系統(tǒng),并自研了告警系統(tǒng),但研發(fā)同學(xué)每人每天都會接收到很多告警,導(dǎo)致重要的告警被淹沒,部分同學(xué)會選擇直接屏蔽掉所有告警,進一步加重問題。告警過多等同于沒有告警。
另外,多個告警之間通常具有一定的關(guān)聯(lián)性,如:SQL執(zhí)行錯誤告警導(dǎo)致異常日志過多告警。而面對雜亂無章的告警,很難快速分析出告警的根本原因。
告警降噪治理十分重要,在此背景下,我們基于Alertmanager擴展研發(fā)了轉(zhuǎn)轉(zhuǎn)告警中心。
二、規(guī)范與SDK
2.1 發(fā)送告警
Alertmanager提供了告警發(fā)送的OpenAPI,其中,告警的labels用于識別同一條告警并對告警去重、降噪,相同labels的告警的annotations會被覆蓋。startsAt與endsAt分別為告警發(fā)生時間與結(jié)束時間。
一條告警從提交到發(fā)送再到接收人的流程大致如下圖所示,其中,Alertmanager需要集群部署來保證高可用性,需要注意的是,發(fā)送告警時不能對集群做負(fù)載均衡,必須要對集群內(nèi)所有的Alertmanager發(fā)送告警才能保證高可用性。

2.2 常用標(biāo)簽
Alertmanager為基于標(biāo)簽的告警降噪,需提前規(guī)范告警常見標(biāo)簽。
- ENV:環(huán)境,如:線上環(huán)境、測試環(huán)境
- APP:服務(wù)名
- SOURCE:告警來源,如:日志告警、JVM告警
- NAME:告警名稱
- LEVEL:告警等級,如:P0告警、P5告警
- INSTANCE:告警實例IP
- RECEIVER_TYPE:告警接受者類型
- RECEIVER:告警接受者,與RECEIVER_TYPE配合使用,如RECEIVER_TYPE=郵件,RECEIVER即為郵箱地址。
Alertmanager標(biāo)簽名的正則規(guī)則為??[a-zA-Z_][a-zA-Z0-9_]*??,在真正發(fā)送通知時,最好將標(biāo)簽名做一次中文映射轉(zhuǎn)換。
2.3 SDK
我們針對Alertmanager開發(fā)了發(fā)送告警的SDK,如下所示,發(fā)送告警非常簡單,SDK默認(rèn)會為每條告警自動增加服務(wù)名、環(huán)境、IP、告警等級,并按照接收方拆開為多條告警發(fā)送。每一項內(nèi)容都是標(biāo)簽,其中value較為特殊,放在了annotations內(nèi),其他均放在了labels內(nèi)用于唯一識別一條告警。
三、告警降噪
3.1 分組去重
分組機制可以將多條告警信息合并成一個通知。例如,當(dāng)集群中有數(shù)百個正在運行的服務(wù)實例,假如此時發(fā)生了網(wǎng)絡(luò)故障,結(jié)果就會有數(shù)百個告警被發(fā)送到Alertmanager。
而作為用戶,可能只希望能夠在一個通知中就能查看哪些服務(wù)實例受到影響。這時可以按照服務(wù)所在集群或者告警名稱對告警進行分組,將這些告警聚合在一起成為一個通知。
Alertmanager可以將收到的告警按照特定的標(biāo)簽分組、去重,并基于以下參數(shù)決定何時發(fā)送組內(nèi)的告警通知,Alertmanager的每一次通知都會包含當(dāng)前組內(nèi)的所有告警。
- 初始等待時間(group_wait):一組告警第一次發(fā)送之前等待的時間,用于等待同一組的更多告警合并發(fā)送。
- 變化等待時間(group_interval):一組已發(fā)送初始通知的告警在接收到新告警或有告警恢復(fù)后,再次發(fā)送通知前等待的時間。
- 重復(fù)等待時間(repeat_interval):一組已發(fā)送初始通知的告警,組內(nèi)告警均沒有恢復(fù)且沒有新增告警,再次發(fā)送通知前等待的時間。
下面以一張圖,來展示從告警產(chǎn)生到合并到某個集合中,到發(fā)送通知的整個過程。三角形和圓形表示不斷產(chǎn)生的告警,矩形代表實際的通知時間以及告警內(nèi)容。

3.2 恢復(fù)通知
Alertmanager自帶恢復(fù)通知,默認(rèn)5m沒有收到告警后,告警將被認(rèn)為恢復(fù),然后會等待group_interval后通知給用戶。發(fā)送告警時也可以指定告警恢復(fù)時間,如下所示:
需要注意的是,endTime如果小于當(dāng)前時間,會認(rèn)為告警在發(fā)出時就已經(jīng)恢復(fù),這條告警不會通知。

3.3 告警分級
我們將告警分為P0~P5六個等級,告警等級默認(rèn)取決于服務(wù)重要性,轉(zhuǎn)轉(zhuǎn)服務(wù)按照重要性分了A、B、C、D、E五個等級,服務(wù)重要性與告警等級的對應(yīng)關(guān)系:A → P1,B → P2,C → P3,D → P4,E → P5。發(fā)送告警時也可以指定告警等級,如下:
告警分級的目的是盡量讓高等級的告警及時發(fā)出,低等級的告警減少用戶打擾次數(shù)。不同等級告警的分組、去重時間均不相同。
如:P4/P5的告警初始時會等待3m收集告警,并將當(dāng)前告警接收者的所有告警匯總到一條通知內(nèi);
P0的告警只會等待15s收集告警,并按照告警接收者、環(huán)境、服務(wù)名、告警來源、告警名稱為維度拆分成多個通知。
告警等級 | 分組標(biāo)簽 | group_wait | group_interval | repeat_interval |
P0 | 告警接收者、環(huán)境、服務(wù)名、告警來源、告警名稱 | 15s | 1m | 30m |
P1 | 告警接收者、環(huán)境、服務(wù)名、告警來源 | 30s | 5m | 1h |
P2 | 告警接收者、環(huán)境、服務(wù)名 | 1m | 5m | 1h |
P3 | 告警接收者、環(huán)境 | 2m | 10m | 2h |
P4/P5 | 告警接收者 | 3m | 10m | 4h |
3.4 通知合并
統(tǒng)一使用Alertmanager webhook通知,一次通知內(nèi)容會包含分組內(nèi)的多個報警,我們會按照告警相似度對告警做合并,如下為6條報警合并成一條通知,其中,告警值與服務(wù)實例一一對應(yīng)。

定義相似度:對于多個報警的labels,只有一個label value不一樣,剩余的label key與label value均相同,則認(rèn)為相似并合并;一次Alertmanager webhook通知可按照相似度拆分成多種告警,不同的告警提取公共標(biāo)簽,最終推送到一條通知內(nèi)。
如下,為4條告警合并到一條通知,可清晰的看到兩臺機器的異常日志報警的原因是由于Druid執(zhí)行SQL錯誤導(dǎo)致。

3.5 告警抑制
抑制是指當(dāng)某一告警發(fā)出后,可以停止重復(fù)發(fā)送由此告警引發(fā)的其它告警的機制。
當(dāng)同一個服務(wù)、環(huán)境、告警來源、IP、接受者、告警名稱,同時出現(xiàn)多個等級的告警時,高等級的告警會抑制低等級告警的通知。
如:告警名稱為FGC次數(shù),P1告警閾值為20次,P2告警為10次,當(dāng)某個實例的FGC次數(shù)達到20次以上時,只會發(fā)送P1告警,不會發(fā)送P2告警。
四、多通知機制
支持企業(yè)微信、企業(yè)微信群、短信、郵件、電話、WebHook,可在一個告警內(nèi)同時指定多種接收方式,我們會自動按照接收人拆分成多條告警。
- 企業(yè)微信、企業(yè)微信群、郵件、WebHook:最詳細(xì),發(fā)送告警與恢復(fù)通知。
- 短信:相對以上,只是不會發(fā)送恢復(fù)通知。
- 電話:不會發(fā)送恢復(fù)通知,并且只會播報報警標(biāo)題與告警服務(wù)名。
五、未恢復(fù)告警
為了防止告警過多時淹沒了重要告警,在每條告警的最后,都提供了一個未恢復(fù)告警鏈接,用于實時查詢當(dāng)前未恢復(fù)的告警。
未恢復(fù)告警擁有三種狀態(tài):活躍、靜默、抑制。其中,活躍狀態(tài)可以設(shè)置靜默,靜默狀態(tài)可以查看被誰靜默。

六、靜默告警
基于Alertmanager OpenAPI,支持基于標(biāo)簽的靜默告警,每條告警通知內(nèi)都提供了一個鏈接用于快速靜默,也可以在未恢復(fù)告警內(nèi)靜默告警。
點擊新增靜默后,會自動補充靜默匹配的標(biāo)簽項,也可以增減標(biāo)簽項,如:去掉INSTANCE標(biāo)簽維度以便匹配所有的機器,修改_RECEIVER為其他人等。需要注意的是,添加靜默時RECEIVER必須要指定。
添加完成后,會自動跳轉(zhuǎn)到靜默列表,并展示剛剛添加的靜默項。

在靜默列表內(nèi)可查詢所有的活躍、過期的靜默項,可編輯、刪除、查看影響的告警。

查看受影響的告警為實時查詢,如果當(dāng)前靜默沒有匹配到任何告警,查詢結(jié)果會為空。

七、告警歷史
告警通知給用戶后,我們會保留三個月的歷史告警記錄列表。

八、總結(jié)
Alertmanager提供了告警降噪的策略,我們在Alertmanager的基礎(chǔ)上制定了標(biāo)簽規(guī)范、告警分級降噪、分級抑制、告警合并,并基于Alertmanager OpenAPI擴展了未恢復(fù)告警、靜默告警、告警歷史。Alertmanager雖然不是告警降噪的銀彈,但也可以解決大部分問題,如果你也面臨著告警轟炸的問題,可以嘗試一下。
關(guān)于作者
苑沖,轉(zhuǎn)轉(zhuǎn)架構(gòu)部存儲服務(wù)負(fù)責(zé)人,主要負(fù)責(zé)MQ、監(jiān)控系統(tǒng)、Redis、KV存儲等。愛學(xué)習(xí),喜歡以辯證思維與變化思維思考。
























