常見開源告警系統對比分析(prometheus、open-falcon、zabbix)

原標題:大規模集羣之告警系統實踐

本文根據鄧歡在2018年7月78日高效運維社區【數據庫專場沙龍】現場演講內容整理而成。


摘要首先介紹告警的選型,然後介紹Alertmanager的實現,最後給大家介紹一下我們的實踐經驗。


分享大綱


一. 告警的選型

二. Alertmanager的實現

三. Alertmanager的實踐


我今天會首先介紹告警的選型,然後介紹Alertmanager的實現,最後給大家介紹一下我們的實踐經驗。


一. 告警的選型



2.png



在告警選型的時候,首先給大家介紹一下我們的需求,然後我將會從需求出發確定方案選型。

 

1.告警需求

 

我們需求主要來自於三個方面:

 

• 告警的對接

• 告警的收斂

• 告警的可用性

 

我們是一家乙方公司,通常服務於各種甲方爸爸,不同甲方爸爸有不同需求。比如甲方爸爸如果有自己的監控系統,希望我們的監控系統能與他們的監控系統進行對接。在與甲方爸爸接觸過程中我們曾遇到這樣的客戶,有一天他跟我們說他最新買的蘋果手機被他換掉了,因爲他的手機經常會死機,死機的原因就是他收到了太多的告警,最後他專門買了一個安卓手機用來接收告警。所以我們第二個告警需求,需要將告警進行收斂。

    

關於第三個問題,我想問下大家,假如長時間沒有收到告警消息,你們是會認爲自己系統運行的很完美,還是會擔心告警系統掛掉了。如果是告警系統掛掉了,不能及時把告警發出來,那麼最後這個鍋到底由誰來背。大家都不希望背鍋,所以告警第三個問題需要解決告警的可用性問題。

    

下面分別從三個方面介紹一下每個方面具體要解決什麼樣的問題。

 

(1)告警的對接


3.png


大多數告警通過監控系統發出,有部分告警可以通過服務直接發出,所以我們希望支持多樣的告警源。對於多樣告警目標,不同公司可能用的辦公軟件都不一樣,有的公司用微信進行通訊,有的公司通過釘釘進行接收消息,而客戶希望我們把告警發到他們聊天工具中去。不同人員的需求也不同,運維人員習慣通過短信接收告警,大BOSS更喜歡用郵件接收告警,所以我們告警對接需要解決的第二個問題是多樣的告警目標。

 

(2)告警收斂


4.png


大家是否遇到這樣問題,收到一個告警然後開始排查問題,但是排查問題過程中告警消息不停地發送過來。處理故障就是精神高度緊張的時候,重複告警消息發過來,不僅對解決問題沒有任何幫助,反而會增加運維人員壓力。所以我們要收斂過多的告警消息。

 

假設有一臺服務器掛掉了,這臺服務器首先會發送一個告警告訴你這臺服務器掛掉了,這臺服務器上面運行其他服務也被監控系統給監測到了,並且這些服務的告警消息也會發出來。但是實際上只有服務器掛掉這一條信息能幫助我們解決問題,所以我們告警的收斂解決關聯告警過多的問題。

 

關於運維期間不希望收到告警主要是因爲運維通常會在大半夜進行,運維期間很有可能會產生一些告警。如果大BOSS接到報警馬上打電話過來,這個壓力可不小。所以這個時間段運維一般不希望把告警發出來,因此告警收斂需要解決的第三個問題是運維期間不希望收到告警。

 

(3)告警的可用性  


5.png


接下來看告警可用性需要解決什麼樣的問題。前面我們說過我們不希望背鍋,所以我們必須要實現告警系統的高可用。

 

關於第二個隔離的故障域,有的監控系統和告警系統綁定在一起,如果監控系統掛掉,告警系統同樣掛掉,所以我們希望監控系統和告警系統是分開部署的。

 

下面我們將針對這三個方面的需求,來進行方案選型。

 

2. 告警的選型

 

1)備選方案


6.png


  • Prometheus

  • Open-falcon

  • Zabbix

 

(2)方案對比


7.png


我們從市面上調研了一些監控系統,其中比較流行的是Prometheus、Open-falcon、Zabbix。根據自身需求對這三個監控系統進行對比,首先我們進行對接方面的對比。這三個系統它們都可以支持多通道的告警源,同時可以支持多通道的告警目標,所以在這個需求上面,這三個方案都是滿足的。


8.png


關於告警的收斂。Zabbix 在告警的收斂上面沒有任何的支持。Open-falcon只進行了一些簡單的收斂,比如一段時間內重複的告警,它不會重複的發送。而Prometheus提供了靈活的規則,能夠滿足在不同場景下的需求。但是通知次數上面,Open-falcon和Zabbix都限制了最大通知次數,Prometheus則沒有最大通知次數的限制,在這一點上上面兩個方案比Prometheus好一點。


9.png


第三個需求方面的支持。首先是Zabbix,監控系統和告警系統綁定在一起,所以它的故障域很大。Open-falcon和Prometheus,其監控系統和告警系統都可以單獨的部署,所以它的故障域相對來說要小,但是Open-falcon所有的組件都支持高可用,除了它的告警系統以外,這一點是比較遺憾的。

 

然後我們還考量了一些其他的方面:


10.png


第一點是配置,Open-falcon和Zabbix都是基於模板的配置,而Prometheus提供的是一種樹形的配置,我們通過對比發現樹形配置比較靈活,而且學習成本也相對較低。

 

第二點是語言,我們公司的大多數產品都是使用GO語言,所以我們希望選擇的方案能夠貼合我們的技術棧。通過以上方面的比較,我們最終選擇了Prometheus作爲我們的方案選型。Prometheus它是一整套的解決方案,它包括了監控系統Prometheus,以及告警的展示Grafana,以及它的告警系統Alertmanager。


總結:

11.png


二.Alertmanager的實現


下面爲大家介紹告警系統Alertmanager的實現。


在介紹實現的時候,首先介紹一下它的架構。然後針對我們前面提到的三點需求對接、收斂和可用性來介紹它的實現,中間可能會穿插一點它的配置。


12.png


首先,輸入和輸出。從輸入上來看,雖然它是Prometheus一個項目,它可以接收Prometheus發出告警,也可以支持其他的監控系統發過來的告警。從輸出來看,每一個告警消息都可以定義不同的接收者,從而實現我們多元化告警目標的需求。


13.png


其次,中間的流程,Alertmanager收到告警之後會將告警進行分組,每一個分組都會有進行抑制和靜默過程,下面還會進行去重,所以它的收斂方式非常的豐富。


14.png


然後,高可用,從這裏可以看出Alertmanager它也提供了高可用了支持。

 

下面我們具體的看一下三個方面的需求如何滿足。

 

1. 對接


15.png


對接方面的需求,首先對接需要接收不同的告警源發送的告警。比如我們用監控系統Prometheus,也有可能我們自己的服務也會發送報警。同時客戶希望將不同的告警發往不同的接收者,所以我們在對Alertmanager收斂之後,把告警發到不同的接收者上面去。


16.png


Alertmanager它通過提供一個統一的API接收不同告警。對於發送的話,在這裏可以配置接收者,接收者不僅僅可以是一個個人,可以是一個團體,也可以是第三方平臺。對於個人而言可以配置郵件,在郵件配置裏面可以配置多個郵件地址,也可以配置一個郵件地址。對企業而言可以配置微信,讓告警發到你們公司微信企業號上;對接第三方平臺的話,提供外部的配置,讓告警發到第三方平臺,比如釘釘類似的通信工具。

 

2. 收斂


17.png


接下來我們看一下Alertmanager關於收斂的支持,Alertmanager收斂提供四種方式:


  • 分組

  • 抑制

  • 靜默

  • 延時



18.png


第一,分組的支持。假設有一大堆關於MySQL的告警,但是希望在分析問題時能夠針對不同的實例進行,所以可以針對不同實例進行分組。每一個告警都會被分往不同實例分組中去,每一個分組最後都會合成一個消息發送給接收者。所以最後運維人員收到的是一封封郵件,而每一封郵件都是關於一個實例的告警。通過這種方式有效的減少了告警消息數量;每一封郵件都是關於一個實例的告警,這種方式可以幫助運維排查一些問題。

    

舉一個具體的例子。假設MySQL A產生了一個報警,另外一臺MySQL B,這臺MySQL掛掉了,監控系統檢測到IO線程和SQL也掛了。通過ID進行分組,不同的實例分配到不同的分組,最後運維將會收到兩條告警消息,一條是關於MySQL A CPU過高的告警;另外一條是關於MySQL B掛掉的告警消息。


19.png


第二,告警的抑制。假設有一臺主機掛掉了,上面運行着MySQL的服務,這個時候主機掛掉和MySQL掛掉的兩條告警到達Alertmanager的順序可能不一樣,運維人員接收的告警順序也可能不一樣。如果先收到MySQL服務掛掉的告警,排查問題的思路可能就往別的方向走了,但是實際上這不是最根本的原因,所以我們可以通過抑制,將主機掛掉的告警把這主機上面MySQL服務掛掉告警抑制掉,最後只收到主機掛掉的告警。這樣能夠把冗餘信息消除掉,最後得到故障發生最本質的原因。

 

這是一個具體的例子,這個例子和上面講的是類似的。假設MySQL服務器A上面運行着MySQL服務,當這臺服務器突然宕機時候,這兩條告警都會出來,但是你配置一條抑制規則,抑制掉MySQL的告警,最後收到服務器掛掉的告警。


20.png


第三,靜默,假設你有一堆分別關於MySQL實例1、2、3的告警,但是出於某些方面的原因不希望收到關於實例1的告警,可以設置靜默規則把它靜默掉,最後就能不再收到關於這臺實例的告警,但是你仍然可以收到其他實例的告警,通過這種方式你可以阻止系統發送一些可以預期的告警。

    

舉例,假設要在MySQL A上面跑一個批處理任務,這個批處理任務消耗系統資源比較大,會觸發這些告警。同時你的系統中還有一臺MySQL B的服務器,這個是對外提供服務的,你不希望把它的報警給靜默掉,所以可以配置一條靜默規則,把MySQL A告警給靜默掉,最後就收不到關於MySQL A的告警,同時其他服務不會被影響到。


21.png


第四,告警的延時,假設系統發生故障產生告警,每分鐘發送一條告警消息,這樣的告警信息十分令人崩潰。Alertmanager提供第一個參數是repeat interval,可以將重複的告警以更大頻率發送,但是隻有這個參數會帶來兩個的問題。第一個問題是告警不能及時收到。假設當前發送一條告警,下一次告警在一個小時之後,但在這一個小時之內系統產生了一條告警,這時告警無法被及時發出去。所以alertmanager提供了第二個參數group inteval,讓報警能夠及時的發送出去。

 

另一個問題,當故障發生時,告警條件一個個被滿足,到達Alertmanager的順序也分先後,所以在最開始的時候可能收到多個消息。Alertmanager提供了第三個參數叫做group wait,在一個分組收到第一條報警消息之後,通過等到group wait,把故障最開始發生時候產生告警收斂掉,最後作爲一條消息發送出來。

 

3.配置


23.png


下面我們講一下Alertmanager的配置,前面我們提到Alertmanager使用的是樹形配置。樹形配置每一個節點定義一個路由規則,匹配路由規則的告警都發送給同一個接收者,前面提到接收者可以通過不同方式進行接收。Alertmanager的樹形配置根接點,必須匹配所有告警,因爲每一條告警都必須有一個接收者。


假設所有的告警中,對於MongoDB和MySQL有專門的人員在負責,所以在根節點下面配了兩個子節點,分別匹配這兩個報警。對於這兩個服務的告警,會分別發送不同運維人員手上。但是在所有的MySQL服務當中有兩類服務是特別重要的,他們分別在group1和group2裏面。所以當希望MySQL服務出現告警,並且是屬於group1時,讓它發往group1的負責人;對於group2出現的問題由group2的負責人去處理;對於其他MySQL出現問題,由MySQL的運維人員去處理。如果是Zabbix,那麼可能將要定義特別多的模板,相對來說Alertmanager提供的配置比較簡潔,而且也相對靈活。

 

這是它配置的實現,配置格式是yml的。首先需要配置接收者,然後通過這個group by定義的標籤將告警進行分組。根路由下面定義了兩個子節點,分別將MongoDB和MySQL的告警發給各自的負責人。在每個節點可以設置不同的延時時間,並且它們分組方式也可以不一樣。

 

4.可用性


24.png


這一小節將介紹Alertmanager高可用的實現方式。在Prometheus項目的官方介紹中,Alertmanager是單獨部署的,每一個Alertmanager它都單獨接收來自Prometheus的告警,然後單獨的將告警進行收斂,最後發送出去。但是會有一個問題,不同的Alertmanager實例可能會發送相同的告警。所以在每一個Alertmanager發送告警之前,它通過Gossip協議去其他實例獲取當前已經有哪些告警發送出去,如果當前想發送的告警已經發送出去了,就不會再發送,從而避免多個Alertmanager發送同一個告警的問題。


三.Alertmanager的實踐

下面我給大家介紹一下我們的實踐經驗,首先我會給大家介紹我們的架構,然後是我們的調度層級,最後我們會介紹一些關於SRE的問題。

 

  • 架 構

  • 調度層級

  • SRE

 

1. 架構


25.png


這是我們的架構,分爲核心區和受管區。

 

在覈心區我們部署監控組件Prometheus和告警組件Alertmanager。在受管區是我們的數據採集服務和被監控的服務。我們通過Agent採集不同服務狀態,Prometheus會定期從Agent收集數據,單獨進行規則判定。如果滿足告警規則的話,會往Alertmanager發送告警。

 

同時Prometheus作爲一個監控組件,也提供了監控數據的來源,可以直接展示系統監控數據。我們把Prometheus發送的告警稱之爲閾值告警,還有一類叫做動作告警。動作告警不像閾值告警定期採集數據獲取,它就是一個動作。比如我們高可用組件把MySQL組成切換了,它會馬上把告警發送出去。

 

2.調度層級


26.png


接下來看我們調度層級,我們使用的是經典的error kernel模型,比如我們的MySQL實例,上面是監控客戶端,監控客戶端定期去MySQL實例採集數據。再上面是我們監控管理端,監控管理端定期從監控客戶端拉取數據,從而進行規則判定。如果它發送告警,會往上一層Alertmanager發送。

 

我們並沒有採用Alertmanager本身提供的高可用實現方式。因爲在我們選型的時候,這個組件還處於活躍的開發狀態,當時它的高可用並不是那麼的可靠,所以我們把Alertmanager和Consul聯合在一起,它實現了Raft協議,我們通過Raft一致性協議來保證Alertmanager高可用。

 

同時我們也實現了反向告警的機制。通常運維人員收到一條告警時候,系統一定出現一個故障,運維人員需要採取動作。但是運維人員收到反向告警不需要採取什麼措施。因爲收到一條反向告警,意味着整個集羣正常工作,如果整個集羣都不能正常工作反向告警是發不出來的。

 

3.SRE

接下來我們講一講SRE。SRE是谷歌的站點可靠性工程,它對監控系統提出了兩點建議。


28.png


第一點建議,報警信息應由系統自動解決,僅僅是當需要的時候通知用戶。其實告警系統的存在完全是因爲系統的不完善導致的,如果系統足夠可靠,不可能發生故障,或者能處理掉髮生的故障。不能處理的時候需要發送一個告警讓人員來介入,但是讓人員來介入效率比較低。

 

第二點建議,收到報警需要用戶立即執行某種操作,解決已經發生或者即將發生的問題。針對SRE建議,我們有一些實踐是遵循了它的建議,但是有一些根據我們的實際需要,我們並沒有遵循它的建議。


29.png


我們第一個實踐是遵循了它的建議,我們之前說過告警分爲閾值告警和動作告警,通常在動作告警當中服務掛掉了會發送一個告警,但是服務被拉起時告警並沒有解決掉,我們遵循了報警自動解決建議,服務拉起之後把原來的告警給解決掉。


30.png


下面一個,我們沒有遵循它的SRE建議,我們在選型的時候說過Alertmanager有個缺陷,不支持通知次數的限制。其實Alertmanager是由谷歌出來一幫人研發的,所以他們所做的工作會遵循SRE。但是實踐中發現大規模集羣通過Alertmanager收斂之後,發出來消息仍然可能特別多,並且過多的告警消息在運維人員解決問題的時候是並沒有幫助的,所以我們爲了人性化的體驗,增加了最大通知次數的限制,雖然這違反了它的一些建議。


31.png


我們下一個實踐的經驗是發送notice級別的告警,這一點也沒有遵循它的建議。因爲按照它的建議不需要運維人員介入的告警不需要發送給運維人員。但是我們需要知道系統發生了這樣一種狀況,並且知道發生狀況的原因是什麼,所以我們增加了notice級別的告警。

    

下面是我們的告警展示,這是我們自己的實踐。


32.png


最後給大家推薦的是《Google SRE運維解密》這本書,這本書是谷歌運維的一些經驗總結,還提出了一些很好的指導建議。這本書在最近剛發佈了第二版,而且最近一個月它都是可以免費下載的,大家感興趣的話可以去看一看。


下載地址:

https://landing.google.com/sre/book.html


謝謝大家!


PPT下載鏈接:

http://github.com/actiontech/slides


原文鏈接:http://blog.51cto.com/13803662/2162462





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章