本文根據鄧歡在2018年7月78日高效運維社區【數據庫專場沙龍】現場演講內容整理而成。html
摘要:首先介紹告警的選型,而後介紹Alertmanager的實現,最後給你們介紹一下咱們的實踐經驗。git
分享大綱:github
一. 告警的選型
二. Alertmanager的實現
三. Alertmanager的實踐數據庫
我今天會首先介紹告警的選型,而後介紹Alertmanager的實現,最後給你們介紹一下咱們的實踐經驗。服務器
一. 告警的選型微信
在告警選型的時候,首先給你們介紹一下咱們的需求,而後我將會從需求出發肯定方案選型。架構
1.告警需求運維
咱們需求主要來自於三個方面:ide
• 告警的對接
• 告警的收斂
• 告警的可用性工具
咱們是一家乙方公司,一般服務於各類甲方爸爸,不一樣甲方爸爸有不一樣需求。好比甲方爸爸若是有本身的監控系統,但願咱們的監控系統能與他們的監控系統進行對接。在與甲方爸爸接觸過程當中咱們曾遇到這樣的客戶,有一天他跟咱們說他最新買的蘋果手機被他換掉了,由於他的手機常常會死機,死機的緣由就是他收到了太多的告警,最後他專門買了一個安卓手機用來接收告警。因此咱們第二個告警需求,須要將告警進行收斂。
關於第三個問題,我想問下你們,假如長時間沒有收到告警消息,大家是會認爲本身系統運行的很完美,仍是會擔憂告警系統掛掉了。若是是告警系統掛掉了,不能及時把告警發出來,那麼最後這個鍋到底由誰來背。你們都不但願背鍋,因此告警第三個問題須要解決告警的可用性問題。
下面分別從三個方面介紹一下每一個方面具體要解決什麼樣的問題。
(1)告警的對接
大多數告警經過監控系統發出,有部分告警能夠經過服務直接發出,因此咱們但願支持多樣的告警源。對於多樣告警目標,不一樣公司可能用的辦公軟件都不同,有的公司用微信進行通信,有的公司經過釘釘進行接收消息,而客戶但願咱們把告警發到他們聊天工具中去。不一樣人員的需求也不一樣,運維人員習慣經過短信接收告警,大BOSS更喜歡用郵件接收告警,因此咱們告警對接須要解決的第二個問題是多樣的告警目標。
(2)告警的收斂
你們是否遇到這樣問題,收到一個告警而後開始排查問題,可是排查問題過程當中告警消息不停地發送過來。處理故障就是精神高度緊張的時候,重複告警消息發過來,不只對解決問題沒有任何幫助,反而會增長運維人員壓力。因此咱們要收斂過多的告警消息。
假設有一臺服務器掛掉了,這臺服務器首先會發送一個告警告訴你這臺服務器掛掉了,這臺服務器上面運行其餘服務也被監控系統給監測到了,而且這些服務的告警消息也會發出來。可是實際上只有服務器掛掉這一條信息能幫助咱們解決問題,因此咱們告警的收斂解決關聯告警過多的問題。
關於運維期間不但願收到告警主要是由於運維一般會在大半夜進行,運維期間頗有可能會產生一些告警。若是大BOSS接到報警立刻打電話過來,這個壓力可不小。因此這個時間段運維通常不但願把告警發出來,所以告警收斂須要解決的第三個問題是運維期間不但願收到告警。
(3)告警的可用性
接下來看告警可用性須要解決什麼樣的問題。前面咱們說過咱們不但願背鍋,因此咱們必需要實現告警系統的高可用。
關於第二個隔離的故障域,有的監控系統和告警系
統綁定在一塊兒,若是監控系統掛掉,告警系統一樣掛掉,因此咱們但願監控系統和告警系統是分開部署的。
下面咱們將針對這三個方面的需求,來進行方案選型。
2.告警的選型
(1)備選方案
· Prometheus
· Open-falcon
· Zabbix
(2)方案對比
咱們從市面上調研了一些監控系統,其中比較流行的是Prometheus、Open-falcon、Zabbix。根據自身需求對這三個監控系統進行對比,首先咱們進行對接方面的對比。這三個系統它們均可以支持多通道的告警源,同時能夠支持多通道的告警目標,因此在這個需求上面,這三個方案都是知足的。
關於告警的收斂。Zabbix 在告警的收斂上面沒有任何的支持。Open-falcon只進行了一些簡單的收斂,好比一段時間內重複的告警,它不會重複的發送。而Prometheus提供了靈活的規則,可以知足在不一樣場景下的需求。可是通知次數上面,Open-falcon和Zabbix都限制了最大通知次數,Prometheus則沒有最大通知次數的限制,在這一點上上面兩個方案比Prometheus好一點。
第三個需求方面的支持。首先是Zabbix,監控系統和告警系統綁定在一塊兒,因此它的故障域很大。Open-falcon和Prometheus,其監控系統和告警系統均可以單獨的部署,因此它的故障域相對來講要小,可是Open-falcon全部的組件都支持高可用,除了它的告警系統之外,這一點是比較遺憾的。
而後咱們還考量了一些其餘的方面:
第一點是配置,Open-falcon和Zabbix都是基於模板的配置,而Prometheus提供的是一種樹形的配置,咱們經過對比發現樹形配置比較靈活,並且學習成本也相對較低。
第二點是語言,咱們公司的大多數產品都是使用GO語言,因此咱們但願選擇的方案可以貼合咱們的技術棧。經過以上方面的比較,咱們最終選擇了Prometheus做爲咱們的方案選型。Prometheus它是一整套的解決方案,它包括了監控系統Prometheus,以及告警的展現Grafana,以及它的告警系統Alertmanager。
總結:
二.Alertmanager的實現
下面爲你們介紹告警系統Alertmanager的實現。
在介紹實現的時候,首先介紹一下它的架構。而後針對咱們前面提到的三點需求對接、收斂和可用性來介紹它的實現,中間可能會穿插一點它的配置。
首先,輸入和輸出。從輸入上來看,雖然它是Prometheus一個項目,它能夠接收Prometheus發出告警,也能夠支持其餘的監控系統發過來的告警。從輸出來看,每個告警消息均可以定義不一樣的接收者,從而實現咱們多元化告警目標的需求。
其次,中間的流程,Alertmanager收到告警以後會將告警進行分組,每個分組都會有進行抑制和靜默過程,下面還會進行去重,因此它的收斂方式很是的豐富。
而後,高可用,從這裏能夠看出Alertmanager它也提供了高可用了支持。
下面咱們具體的看一下三個方面的需求如何知足。
1. 對接
對接方面的需求,首先對接須要接收不一樣的告警源發送的告警。好比咱們用監控系統Prometheus,也有可能咱們本身的服務也會發送報警。同時客戶但願將不一樣的告警發往不一樣的接收者,因此咱們在對Alertmanager收斂以後,把告警發到不一樣的接收者上面去。
Alertmanager它經過提供一個統一的API接收不一樣告警。對於發送的話,在這裏能夠配置接收者,接收者不只僅能夠是一個我的,能夠是一個團體,也能夠是第三方平臺。對於我的而言能夠配置郵件,在郵件配置裏面能夠配置多個郵件地址,也能夠配置一個郵件地址。對企業而言能夠配置微信,讓告警發到大家公司微信企業號上;對接第三方平臺的話,提供外部的配置,讓告警發到第三方平臺,好比釘釘相似的通訊工具。
2.收斂
接下來咱們看一下Alertmanager關於收斂的支持,Alertmanager收斂提供四種方式:
· 分組
· 抑制
· 靜默
· 延時
第一,分組的支持。假設有一大堆關於MySQL的告警,可是但願在分析問題時可以針對不一樣的實例進行,因此能夠針對不一樣實例進行分組。每個告警都會被分往不一樣實例分組中去,每個分組最後都會合成一個消息發送給接收者。因此最後運維人員收到的是一封封郵件,而每一封郵件都是關於一個實例的告警。經過這種方式有效的減小了告警消息數量;每一封郵件都是關於一個實例的告警,這種方式能夠幫助運維排查一些問題。
舉一個具體的例子。假設MySQL A產生了一個報警,另一臺MySQL B,這臺MySQL掛掉了,監控系統檢測到IO線程和SQL也掛了。經過ID進行分組,不一樣的實例分配到不一樣的分組,最後運維將會收到兩條告警消息,一條是關於MySQL A CPU太高的告警;另一條是關於MySQL B掛掉的告警消息。
第二,告警的抑制。假設有一臺主機掛掉了,上面運行着MySQL的服務,這個時候主機掛掉和MySQL掛掉的兩條告警到達Alertmanager的順序可能不同,運維人員接收的告警順序也可能不同。若是先收到MySQL服務掛掉的告警,排查問題的思路可能就往別的方向走了,可是實際上這不是最根本的緣由,因此咱們能夠經過抑制,將主機掛掉的告警把這主機上面MySQL服務掛掉告警抑制掉,最後只收到主機掛掉的告警。這樣可以把冗餘信息消除掉,最後獲得故障發生最本質的緣由。
這是一個具體的例子,這個例子和上面講的是相似的。假設MySQL服務器A上面運行着MySQL服務,當這臺服務器忽然宕機時候,這兩條告警都會出來,可是你配置一條抑制規則,抑制掉MySQL的告警,最後收到服務器掛掉的告警。
第三,靜默,假設你有一堆分別關於MySQL實例一、二、3的告警,可是出於某些方面的緣由不但願收到關於實例1的告警,能夠設置靜默規則把它靜默掉,最後就能再也不收到關於這臺實例的告警,可是你仍然能夠收到其餘實例的告警,經過這種方式你能夠阻止系統發送一些能夠預期的告警。
舉例,假設要在MySQL A上面跑一個批處理任務,這個批處理任務消耗系統資源比較大,會觸發這些告警。同時你的系統中還有一臺MySQL B的服務器,這個是對外提供服務的,你不但願把它的報警給靜默掉,因此能夠配置一條靜默規則,把MySQL A告警給靜默掉,最後就收不到關於MySQL A的告警,同時其餘服務不會被影響到。
第四,告警的延時,假設系統發生故障產生告警,每分鐘發送一條告警消息,這樣的告警信息十分使人崩潰。Alertmanager提供第一個參數是repeat interval,能夠將重複的告警以更大頻率發送,可是隻有這個參數會帶來兩個的問題。第一個問題是告警不能及時收到。假設當前發送一條告警,下一次告警在一個小時以後,但在這一個小時以內系統產生了一條告警,這時告警沒法被及時發出去。因此alertmanager提供了第二個參數group inteval,讓報警可以及時的發送出去。
另外一個問題,當故障發生時,告警條件一個個被知足,到達Alertmanager的順序也分前後,因此在最開始的時候可能收到多個消息。Alertmanager提供了第三個參數叫作group wait,在一個分組收到第一條報警消息以後,經過等到group wait,把故障最開始發生時候產生告警收斂掉,最後做爲一條消息發送出來。
3.配置
下面咱們講一下Alertmanager的配置,前面咱們提到Alertmanager使用的是樹形配置。樹形配置每個節點定義一個路由規則,匹配路由規則的告警都發送給同一個接收者,前面提到接收者能夠經過不一樣方式進行接收。Alertmanager的樹形配置根接點,必須匹配全部告警,由於每一條告警都必須有一個接收者。
假設全部的告警中,對於MongoDB和MySQL有專門的人員在負責,因此在根節點下面配了兩個子節點,分別匹配這兩個報警。對於這兩個服務的告警,會分別發送不一樣運維人員手上。可是在全部的MySQL服務當中有兩類服務是特別重要的,他們分別在group1和group2裏面。因此當但願MySQL服務出現告警,而且是屬於group1時,讓它發往group1的負責人;對於group2出現的問題由group2的負責人去處理;對於其餘MySQL出現問題,由MySQL的運維人員去處理。若是是Zabbix,那麼可能將要定義特別多的模板,相對來講Alertmanager提供的配置比較簡潔,並且也相對靈活。
這是它配置的實現,配置格式是yml的。首先須要配置接收者,而後經過這個group by定義的標籤將告警進行分組。根路由下面定義了兩個子節點,分別將MongoDB和MySQL的告警發給各自的負責人。在每一個節點能夠設置不一樣的延時時間,而且它們分組方式也能夠不同。
4.可用性
這一小節將介紹Alertmanager高可用的實現方式。在Prometheus項目的官方介紹中,Alertmanager是單獨部署的,每個Alertmanager它都單獨接收來自Prometheus的告警,而後單獨的將告警進行收斂,最後發送出去。可是會有一個問題,不一樣的Alertmanager實例可能會發送相同的告警。因此在每個Alertmanager發送告警以前,它經過Gossip協議去其餘實例獲取當前已經有哪些告警發送出去,若是當前想發送的告警已經發送出去了,就不會再發送,從而避免多個Alertmanager發送同一個告警的問題。
三.Alertmanager的實踐
下面我給你們介紹一下咱們的實踐經驗,首先我會給你們介紹咱們的架構,而後是咱們的調度層級,最後咱們會介紹一些關於SRE的問題。
· 架構
· 調度層級
· SRE
1. 架構
這是咱們的架構,分爲核心區和受管區。
在覈心區咱們部署監控組件Prometheus和告警組件Alertmanager。在受管區是咱們的數據採集服務和被監控的服務。咱們經過Agent採集不一樣服務狀態,Prometheus會按期從Agent收集數據,單獨進行規則斷定。若是知足告警規則的話,會往Alertmanager發送告警。
同時Prometheus做爲一個監控組件,也提供了監控數據的來源,能夠直接展現系統監控數據。咱們把Prometheus發送的告警稱之爲閾值告警,還有一類叫作動做告警。動做告警不像閾值告警按期採集數據獲取,它就是一個動做。好比咱們高可用組件把MySQL組成切換了,它會立刻把告警發送出去。
2.調度層級
接下來看咱們調度層級,咱們使用的是經典的error kernel模型,好比咱們的MySQL實例,上面是監控客戶端,監控客戶端按期去MySQL實例採集數據。再上面是咱們監控管理端,監控管理端按期從監控客戶端拉取數據,從而進行規則斷定。若是它發送告警,會往上一層Alertmanager發送。
咱們並無採用Alertmanager自己提供的高可用實現方式。由於在咱們選型的時候,這個組件還處於活躍的開發狀態,當時它的高可用並非那麼的可靠,因此咱們把Alertmanager和Consul聯合在一塊兒,它實現了Raft協議,咱們經過Raft一致性協議來保證Alertmanager高可用。
同時咱們也實現了反向告警的機制。一般運維人員收到一條告警時候,系統必定出現一個故障,運維人員須要採起動做。可是運維人員收到反向告警不須要採起什麼措施。由於收到一條反向告警,意味着整個集羣正常工做,若是整個集羣都不能正常工做反向告警是發不出來的。
3.SRE
接下來咱們講一講SRE。SRE是谷歌的站點可靠性工程,它對監控系統提出了兩點建議。
第一點建議,報警信息應由系統自動解決,僅僅是當須要的時候通知用戶。其實告警系統的存在徹底是由於系統的不完善致使的,若是系統足夠可靠,不可能發生故障,或者能處理掉髮生的故障。不能處理的時候須要發送一個告警讓人員來介入,可是讓人員來介入效率比較低。
第二點建議,收到報警須要用戶當即執行某種操做,解決已經發生或者即將發生的問題。針對SRE建議,咱們有一些實踐是遵循了它的建議,可是有一些根據咱們的實際須要,咱們並無遵循它的建議。
咱們第一個實踐是遵循了它的建議,咱們以前說過告警分爲閾值告警和動做告警,一般在動做告警當中服務掛掉了會發送一個告警,可是服務被拉起時告警並無解決掉,咱們遵循了報警自動解決建議,服務拉起以後把原來的告警給解決掉。
下面一個,咱們沒有遵循它的SRE建議,咱們在選型的時候說過Alertmanager有個缺陷,不支持通知次數的限制。其實Alertmanager是由谷歌出來一幫人研發的,因此他們所作的工做會遵循SRE。可是實踐中發現大規模集羣經過Alertmanager收斂以後,發出來消息仍然可能特別多,而且過多的告警消息在運維人員解決問題的時候是並無幫助的,因此咱們爲了人性化的體驗,增長了最大通知次數的限制,雖然這違反了它的一些建議。
咱們下一個實踐的經驗是發送notice級別的告警,這一點也沒有遵循它的建議。由於按照它的建議不須要運維人員介入的告警不須要發送給運維人員。可是咱們須要知道系統發生了這樣一種情況,而且知道發生情況的緣由是什麼,因此咱們增長了notice級別的告警。
下面是咱們的告警展現,這是咱們本身的實踐。
最後給你們推薦的是《Google SRE運維解密》這本書,這本書是谷歌運維的一些經驗總結,還提出了一些很好的指導建議。這本書在最近剛發佈了第二版,並且最近一個月它都是能夠免費下載的,你們感興趣的話能夠去看一看。
下載地址:
https://landing.google.com/sr...
謝謝你們。
PPT下載連接:
http://github.com/actiontech/...