<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          搞懂 Prometheus 告警神器 Alertmanager

          共 5132字,需瀏覽 11分鐘

           ·

          2021-03-09 19:23

          作者:吳葉磊

          轉自:https://aleiwu.com/post/alertmanager


          警報是監(jiān)控系統(tǒng)中必不可少的一塊, 當然了, 也是最難搞的一塊. 我們乍一想, 警報似乎很簡單一件事:

          假如發(fā)生了異常情況, 發(fā)送或郵件/消息通知給某人或某頻道

          一把梭搞起來之后, 就不免有一些小麻煩:

          • 這個啊…一天中總有那么幾次波動, 也難修難查了, 算了算了不看了

          • 警報太多了, 實在看不過來, 屏蔽/歸檔/放生吧…

          • 有毒吧, 這個閾值也太低了

          • 臥槽, 這些警報啥意思啊, 發(fā)給我干嘛啊?

          • 臥槽臥槽臥槽, 怎么一下子幾十百來條警報, 哦…原來網絡出問題了全崩了

          到最后我們還能總結出一個奇怪的規(guī)律:

          這世界上只有兩種警報,一種是瘋狂報警但是沒有卵用完全沒人看的警報,一種是非常有效大家都想看但在用戶反饋前從來都報不出來的警報。—— 魯迅(

          玩笑歸玩笑,但至少我們能看出,警報不是一個簡單的計算+通知系統(tǒng)。只是,”做好警報”這件事本身是個綜合問題,代碼能解決的也只是其中的一小部分,更多的事情要在組織、人事和管理上去做。我掰不出那么有深度的文章,這篇文章就專注一點,只講代碼部分里的通知,也就是 Prometheus 生態(tài)中的 Alertmanager 這個組件。

          為什么要 Alertmanager?

          我們先介紹一點背景知識,Prometheus 生態(tài)中的警報是在 Prometheus Server 中計算警報規(guī)則(Alert Rule)并產生的,而所謂計算警報規(guī)則,其實就是周期性地執(zhí)行一段 PromQL,得到的查詢結果就是警報,比如:

          1
          node_load5 > 20

          這個 PromQL 會查出所有”在最近一次采樣中,5分鐘平均 Load 大于 20”的時間序列。這些序列帶上它們的標簽就被轉化為警報。

          只是,當 Prometheus Server 計算出一些警報后,它自己并沒有能力將這些警報通知出去,只能將警報推給 Alertmanager,由 Alertmanager 進行發(fā)送。

          這個切分,一方面是出于單一職責的考慮,讓 Prometheus “do one thing and do it well”, 另一方面則是因為警報發(fā)送確實不是一件”簡單”的事,需要一個專門的系統(tǒng)來做好它。可以這么說,Alertmanager 的目標不是簡單地”發(fā)出警報”,而是”發(fā)出高質量的警報”。它提供的高級功能包括但不限于:

          • Go Template 渲染警報內容;

          • 管理警報的重復提醒時機與消除后消除通知的發(fā)送;

          • 根據(jù)標簽定義警報路由,實現(xiàn)警報的優(yōu)先級、接收人劃分,并針對不同的優(yōu)先級和接收人定制不同的發(fā)送策略;

          • 將同類型警報打包成一條通知發(fā)送出去,降低警報通知的頻率;

          • 支持靜默規(guī)則: 用戶可以定義一條靜默規(guī)則,在一段時間內停止發(fā)送部分特定的警報,比如已經確認是搜索集群問題,在修復搜索集群時,先靜默掉搜索集群相關警報;

          • 支持”抑制”規(guī)則(Inhibition Rule): 用戶可以定義一條”抑制”規(guī)則,規(guī)定在某種警報發(fā)生時,不發(fā)送另一種警報,比如在”A 機房網絡故障”這條警報發(fā)生時,不發(fā)送所有”A 機房中的警報”;

          假如你很忙,那么讀到這里就完全 OK 了,反正這類文章最大的作用就是讓我們”知道有 X 這回事,大概了解有啥特性,當有需求匹配時,能想到試試看 X 合不合適“,其中 X = Alertmanager。當然,假如你是個好奇寶寶,那么還可以看看下面的解析。

          Alertmanager 內部架構

          先看官方文檔中的架構圖:


          5f74efe9c5ebbb8a94e1a839977d8678.webp


          1. 從左上開始,Prometheus 發(fā)送的警報到 Alertmanager;

          2. 警報會被存儲到 AlertProvider 中,Alertmanager 的內置實現(xiàn)就是包了一個 map,也就是存放在本機內存中,這里可以很容易地擴展其它 Provider;

          3. Dispatcher 是一個單獨的 goroutine,它會不斷到 AlertProvider 拉新的警報,并且根據(jù) YAML 配置的?Routing Tree?將警報路由到一個分組中;

          4. 分組會定時進行 flush (間隔為配置參數(shù)中的 group_interval), flush 后這組警報會走一個?Notification Pipeline?鏈式處理;

          5. Notification Pipeline?為這組警報確定發(fā)送目標,并執(zhí)行抑制邏輯,靜默邏輯,去重邏輯,發(fā)送與重試邏輯,實現(xiàn)警報的最終投遞;

          下面就分開講一講核心的兩塊:

          1. Dispatcher 中的 Routing Tree 的實現(xiàn)與設計意圖

          2. Notification Pipeline 的實現(xiàn)與設計意圖

          Routing Tree

          Routing Tree 的是一顆多叉樹,節(jié)點的數(shù)據(jù)結構定義如下:


          e6b2a16b01764684bb2f8928896fe16b.webp


          具體的處理代碼很簡單,深度優(yōu)先搜索:警報從 root 開始匹配(root 默認匹配所有警報),然后根據(jù)節(jié)點中定義的 Matchers 檢測警報與節(jié)點是否匹配,匹配則繼續(xù)往下搜索,默認情況下第一個”最深”的 match (也就是 DFS 回溯之前的最后一個節(jié)點)會被返回。特殊情況就是節(jié)點配置了 Continue=true,這時假如這個節(jié)點匹配上了,那不會立即返回,而是繼續(xù)搜索,用于支持警報發(fā)送給多方這種場景(比如”抄送”)


          1908d0c9f031ef15fe07f1399a67bceb.webp


          為什么要設計一個復雜的 Routing Tree 邏輯呢?我們看看 Prometheus 官方的配置例子:為了簡化編寫,Alertmanager 的設計是根節(jié)點的所有參數(shù)都會被子節(jié)點繼承(除非子節(jié)點重寫了這個參數(shù))


          70d1809e5cf8043f284969172066d5bc.webp


          總結一下,Routing Tree 的設計意圖是讓用戶能夠非常自由地給警報歸類,然后根據(jù)歸類后的類別來配置要發(fā)送給誰以及怎么發(fā)送:

          • 發(fā)送給誰?上面已經做了很好的示例,數(shù)據(jù)庫警報前端警報都有特定的接收組,都沒有匹配上那么就是默認警報, 發(fā)送給默認接收組

          • 怎么發(fā)送?對于一類警報,有個多個字段來配置發(fā)送行為:

            • 配置中的 ‘數(shù)據(jù)庫警報’ 是按 ‘集群’ 和 ‘規(guī)則名’ 分組的,這表明對于數(shù)據(jù)庫警報,我們關心的是“哪個集群的哪個規(guī)則出問題了”,比如一個時間段內,’華東’集群產生了10條 ‘API響應時間過長’ 警報,這些警報就會聚合在一個通知里發(fā)出來;

            • 配置中的 ‘前端警報’ 是按 ‘產品’ 和 ‘環(huán)境’ 分組的, 這表明對于前端警報,我們關心的是“哪個產品的哪個環(huán)境出問題了

            • group_by決定了警報怎么分組,每個 group 只會定時產生一次通知,這就達到了降噪的效果,而不同的警報類別分組方式顯然是不一樣的,舉個例子:

            • group_interval 和 group_wait: 控制分組的細節(jié),不細談,其中 group_interval 控制了這個分組最快多久執(zhí)行一次 Notification Pipeline

            • repeat_interval: 假如一個相同的警報一直 FIRING,Alertmanager 并不會一直發(fā)送警報,而會等待一段時間,這個等待時間就是 repeat_interval,顯然,不同類型警報的發(fā)送頻率也是不一樣的

          group_interval 和 repeat_interval 的區(qū)別會在下文中詳述

          Notification Pipeline

          由 Routing Tree 分組后的警報會觸發(fā) Notification Pipeline:

          • 當一個 AlertGroup 新建后,它會等待一段時間(group_wait 參數(shù)),再觸發(fā)第一次 Notification Pipeline

          • 假如這個 AlertGroup 持續(xù)存在,那么之后每隔一段時間(group_interval 參數(shù)),都會觸發(fā)一次 Notification Pipeline

          每次觸發(fā) Notification Pipeline,AlertGroup 都會將組內所有的 Alert 作為一個列表傳進 Pipeline, Notification Pipeline 本身是一個按照責任鏈模式設計的接口,MultiStage 這個實現(xiàn)會鏈式執(zhí)行所有的 Stage:


          146b48932366b28b998671e2e9c5d757.webp


          MultiStage 里塞的就是開頭架構圖里畫的 InhibitStage、SilenceStage…這么一條鏈式處理的流程,這里要提一下,官方的架構圖畫錯了,RoutingStage 其實處在整個 Pipeline 的首位,不過這個順序并不影響邏輯。要重點說的是DedupStageNotifySetStage它倆協(xié)同負責去重工作,具體做法是:

          • NotifySetStage 會為發(fā)送成功的警報記錄一條發(fā)送通知,key 是接收組名字’+’GroupKey 的 key 值,value 是當前 Stage 收到的 []Alert (這個列表和最開始進入 Notification Pipeline 的警報列表有可能是不同的,因為其中有些 Alert 可能在前置 Stage 中已經被過濾掉了)

          • DedupStage 中會以’接收組名字’+’GroupKey 的 key 值’為 key 查詢通知記錄,假如:

            • 假如 A 是 S 的子集,那么表明 A 和 S 重復,這時候要根據(jù) repeat_interval 來決定是否再次發(fā)送:

            • 假如 A 不是 S 的子集,那么 A 和 S 不重復,需要再發(fā)送一次;上面的表述可能有些抽象,最后表現(xiàn)出來的結果是:

            • 距離 S 的發(fā)送時間已經過去了足夠久(repeat_interval),那么我們要再發(fā)送一遍;

            • 距離 S 的發(fā)送時間還沒有達到 repeat_interval,那么為了降低警報頻率,觸發(fā)去重邏輯,這次我們就不發(fā)了;

            • 查詢無結果,那么這條通知沒發(fā)過,為這組警報發(fā)送一條通知;

            • 查詢有結果,那么查詢得到已經發(fā)送過的一組警報 S,判斷當前的這組警報 A 是否為 S 的子集:

          • 假如一個 AlertGroup 里的警報一直發(fā)生變化,那么雖然每次都是新警報,不會被去重,但是由于 group_interval (假設是5分鐘)存在,這個 AlertGroup 最多 5 分鐘觸發(fā)一次 Notification Pipeline,因此最多也只會 5 分鐘發(fā)送一條通知;

          • 假如一個 AlertGroup 里的警報一直不變化,就是那么幾條一直 FIRING 著,那么雖然每個 group_interval 都會觸發(fā) Notification Pipeline,但是由于 repeate_interval(假設是1小時)存在,因此最多也只會每 1 小時為這個重復的警報發(fā)送一條通知;再說一下 Silence 和 Inhibit,兩者都是基于用戶主動定義的規(guī)則的:

          • Silence Rule:靜默規(guī)則用來關閉掉部分警報的通知,比如某個性能問題已經修復了,但需要排期上線,那么在上線前就可以把對應的警報靜默掉來減少噪音;

          • Inhibit Rule:抑制規(guī)則用于在某類警報發(fā)生時,抑制掉另一類警報,比如某個機房宕機了,那么會影響所有上層服務,產生級聯(lián)的警報洪流,反而會掩蓋掉根本原因,這時候抑制規(guī)則就有用了;因此 Notification Pipeline 的設計意圖就很明確了:通過一系列邏輯(如抑制、靜默、去重)來獲得更高的警報質量,由于警報質量的維度很多(剔除重復、類似的警報,靜默暫時無用的警報,抑制級聯(lián)警報),因此 Notification Pipeline 設計成了責任鏈模式,以便于隨時添加新的環(huán)節(jié)來優(yōu)化警報質量

          結語

          Alertmanager 整體的設計意圖就是奔著治理警報(通知)去的,首先它用 Routing Tree 來幫助用戶定義警報的歸類與發(fā)送邏輯,然后再用 Notification Pipeline 來做抑制、靜默、去重以提升警報質量。這些功能雖然不能解決”警報”這件事中所有令人頭疼的問題,但確實為我們著手去解決”警報質量”相關問題提供了趁手的工具。


          - END -

          公眾號后臺回復「加群」加入一線高級工程師技術交流群,一起交流進步。

          ?推薦閱讀?

          31天拿下K8s含金量最高的CKA證書!【本周開班】2021最新 Kubernetes 運維架構師實戰(zhàn)指南?Zabbix 通過 API 監(jiān)控 Kubernetes
          DevOps知識框架體系和最佳實踐案例整理
          企業(yè)級日志平臺新秀Loki,比ELK輕量多了~Kubernetes Ingress-Nginx 實現(xiàn)藍綠、灰度發(fā)布Prometheus 監(jiān)控服務端口、網站狀態(tài)等(黑盒監(jiān)測)Kubernetes 學習筆記總結,超詳細!Kubernetes生產環(huán)境最佳實踐



          點亮,服務器三年不宕機97b60a701b3fa2a64fdf5ae79b74fb52.webp

          瀏覽 57
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  老女人操逼视频 | 日韩无码免费播放 | www.大鸡巴免费99 | 日本少妇后入 | 台湾午夜视频 |