去哪兒網企業級監控平臺-Watcher

張哥說技術發表於2023-04-25

來源:Qunar技術沙龍

一、背景

目前開源的監控系統越來越多,不同的系統針對的側重點和特性也不同,像 Zabbix/Nagios 這種老牌的監控系統側重於主機系統層監控和告警,比如 Zabbix 和 Nagios 都自帶有一套完善的系統層面監控外掛,而且還允許運維很方便的利用 Shell 指令碼或任何其他指令碼語言來擴充套件自己想要的外掛,同時 Zabbix 還提供了比較便利的 Discovery 功能,建立一套模板後,便能自動發現和檢測相應主機狀態,省掉了繁瑣的配置過程。而 Graphite/Prometheus 這樣的則更兼顧業務應用層監控,它們提供了一套機制,應用可以在程式碼裡記錄自己在執行時的狀態資料,然後透過 Exporter 或者 Push 的方式將狀態資料暴露或推送到 Server 端,Server 儲存在時序 DB 中用於之後的分析、檢視和告警等。

很多企業在用開源軟體的一個路徑大概都是這樣的,純開源使用 → 少量的定製化開發或外層封裝 → 深度的二次開發 → 自研。 

去哪兒網的監控平臺早期的時候用的也是用的純原生方式,但隨著之後的發展這種形式已經不能滿足我們的需求,因此我們開始設計自己的監控系統,從使用者角度看我們要提供統一入口的一站式的監控平臺,避免開發在各個系統間跳來跳去,要更友好的支援應用監控,要有更便捷的指標檢視和快速定位,要更方便的讓使用者自己配置告警以及告警升級之類的告警操作等。基於此我們開發了 Watcher 監控系統。

去哪兒網企業級監控平臺-Watcher

Watcher 是去哪兒網內部的一站式監控平臺,它的開發方式是大部分自研元件加上小部分二開元件的方式完成的。目前每分鐘收集儲存的指標總量在億級,檢測和處理的報警量是百萬級的。因為考慮到資料量比較大,所以我們要求監控體系中任何元件都能夠很好的水平擴充套件。

二、打造符合需求的企業級監控平臺

由於早期使用的開源監控已經不能滿足我們的需求了,因此我們需要考慮建設自己的監控平臺。這個平臺要能解決幾個問題:

  1. 提供一站式監控告警的能力

  2. 提供更友好的應用層面或應用維度的監控能力

  3. 統一監控資源,讓使用者自己管理,同時提供足夠方便的快速排障能力。

  4. 使用簡單,因為使用者是面對全公司的,其中有技術同學和非技術同學,所以要避免過高的學習和使用成本。


1. 平臺核心功能設計

Grafana 本身就提供了很優秀的監控繪圖能力和多資料來源的支援,並且是非常的靈活,允許使用者從各種資料來源選擇指標資料繪製各種型別的圖表並儲存下來。但 Grafana 在企業的使用中也是會有一些不便的,比如:

  • 檢視指標不夠便捷,早期的 Grafana 是沒有 Explore 功能的,使用者在 Grafana 中檢視指標必須要先新建一個 Panel,然後在 Panel 中輸入對應的查詢表示式才能看到自己的指標,這對於有很多指標,並且只是臨時性的檢視一次的這種場景來說就極為不便了。

  • 皮膚管理不方便,新版的 Grafana 給皮膚增加了目錄和標籤功能,但是對於皮膚比較多組織架構比較深的時候管理仍然不夠便捷。

  • 沒有模板功能,比如在一些主機監控的場景中,我們要檢視主機的監控內容基本是一樣的,比如主機的 CPU、記憶體、Load、網路、磁碟等等,在這種場景如果每臺機器都要手工的配置出來一個皮膚,那工作量還是很大的,即便是使用 Variables 能力(早期叫 Templating),在主機量很多時,在下拉框裡去搜尋使用也很困難。

  • 報警功能無法滿足企業需求


基於這些原因我們的控制面選擇對 Grafana 進行二次開發。

Watcher 整體上分為應用空間、公共空間、使用者空間、報警空間、全域性配置、系統配置等6個功能模組,其中

  • 應用空間:以應用為維度管理所有的監控資源,包括使用者自己上報的指標資料和當前應用下的主機、Pod、DB、redis、負載均衡等監控資訊。

  • 公共空間:公共空間提供了使用者自定義皮膚的能力,以及多元的函式分析能力,使用者可以在公共空間建立自己的皮膚進行多指標聯合分。

  • 使用者空間:類似公共空間,只不過屬私人空間,其他人無權檢視。

  • 報警空間:管理所有的報警,可以快速基於 appCode、指標、聯絡人等檢索報警,以及修改和配置報警。

  • 全域性配置:顧名思義提供了一些個人全域性屬性上的配置修改,如 主題、圖上是否關聯故障事件、使用者組管理以及其他便捷的工具。

  • 系統配置:這部分控制監控平臺的一些展示行為和全域性的外掛配置,只有管理員有許可權。


下面介紹下我們平臺的部分核心功能設計:

1.1. 應用維度的監控管理

去哪兒網是以應用維度來管理各種資源的包括監控資源,我們給每一個應用會起一個唯一標識叫做 AppCode,抽象出 AppCode 後,我們可以對這個 AppCode 可以在多個系統進行連通,多系統可以資料共享,而且在各系統設計時統一基於 AppCode 的概念來設計,這樣對於所有人在使用這個系統時候也能降低很多理解成本。

因此我們在 Watcher 上建立了應用空間,應用空間管理了一個應用所有的監控資源,並且與服務樹打通,可以快速檢索或瀏覽自己的 appCode 。

多環境指標檢視

Watcher 打通了環境管理,可以採集不同環境的指標如 prod、beta,並且能夠自動列出當前應用的所有環境,使用者可以快捷的找到自己對應環境指標。

去哪兒網企業級監控平臺-Watcher

指標檢索和指標瀏覽

預設情況下,使用者可以輸入關鍵字或者正則來快速檢索自己的指標,如上圖,但如果實在忘記了自己的指標名,也是點選搜尋框後面的指標樹來瀏覽自己當前應用當前環境下的所有指標的。 如下圖:

去哪兒網企業級監控平臺-Watcher

沒錯,指標也會被組裝成一棵樹形,不同於現在的 Prometheus 的 Tag 指標的扁平化形式,在 Qunar 指標命名也是層級化的,是以 "metic.name.xxx" 這種形式組合成一個 Metric,每一個點便是 Tree 的一級,樹形結構天然帶有目錄作用,因此以樹形結構組織一組指標可讀性比較好。

單機維度指標

Watcher 在採集指標的時候除了記錄每臺主機上報的指標資料之外,還會自動聚合應用維度的指標,比如應用有3臺主機上報了"myapi.qps"指標,那麼每臺主機都有自己的 myapi.qps 指標,同時會聚合出一個總的 myapi.qps 指標,而通常我們新增監控也是監控應用維度的 myapi.qps 指標,如果指標有波動想要繼續排查問題,就需要看每臺主機的 qps 是否有波動,這個時候就可以如下圖點選指標上的 “單機數” 就會列出每臺主機的 qps 趨勢,方便使用者定位根因。

去哪兒網企業級監控平臺-Watcher

去哪兒網企業級監控平臺-Watcher
應用主機資源監控

Watcher 打通了 CMDB,可以即時動態的的在應用空間中快速列出自己應用的主機/Pod 資源,以及這些資源的監控趨勢,如 CPU、Load、記憶體、網路等等,無須任何手動的配置操作。

去哪兒網企業級監控平臺-Watcher

DB監控

同樣的在應用空間,使用者可以選擇自己的 DB,這樣就能自動列出當前 DB 的所有狀態指標監控,方便使用者快速定位 DB 問題。

去哪兒網企業級監控平臺-Watcher

域名監控

如果你的應用以域名的形式對外提供服務,那你只要輸入自己的域名就能看到自己域名當前的一些 QPS 和網路流量等監控趨勢。

去哪兒網企業級監控平臺-Watcher

1.2. 公共空間自定義皮膚管理

樹形結構管理皮膚

我們將 Grafana 扁平化的皮膚管理改造成了目錄樹結構的皮膚管理,這在皮膚比較多的時候非常有用,而且層級分明對於人記憶和查詢都比較友好,同時也提供了搜尋功能,可以針對關鍵字快速搜尋自己的皮膚。同時可以給目錄樹做更細緻的許可權管理,比如是否僅檢視,檢視和編輯,還是無許可權訪問等,這些許可權也可以從父節點繼承到子節點。

去哪兒網企業級監控平臺-Watcher

許可權管理

樹形結構上的許可權很管理,由於實現了繼承特性,使用者想要在一定範圍內新增或刪除許可權時不必一個一個節點去操作,只需要在父節點上設定對應的許可權即可,比如在父節點設定了Owner許可權那麼也可以檢視子節點的皮膚。

去哪兒網企業級監控平臺-Watcher

報警聯動

在公共空間的皮膚上配置的報警,可以與皮膚狀態聯動,當報警發生異常時,皮膚上能立即感知到。

去哪兒網企業級監控平臺-Watcher

去哪兒網企業級監控平臺-Watcher

1.3. 報警管理

報警管理模組,解決了兩個問題:

  1. 統一了告警配置和告警檢視,使用者不在需要到多個系統檢視自己告警,告警依然支援根據 AppCode 來搜尋自己配置過的告警

  2. 豐富告警周邊元件,方便使用者在發生告警時快速定位問題。比如 ①告警與 Trace 進行關聯,當告警時可以檢索到與當前異常指標有關的 trace id ;②與根因分析系統關聯,當發生異常告警時,利用根因分析系統輔助定位。

告警管理分為業務告警和主機告警:

  1. 業務告警是指使用者應用埋點監控的Metrics新增的告警,使用者可以任意增加、刪除、修改、設定通知聯絡人等。

  2. 主機告警這塊我們實現了類似Zabbix的主機模板和Discovery功能,使用者可以配置一類主機監控模板,同時設定Discovery規則,一旦當有匹配類別的主機上線,則自動應用這些監控和告警。

去哪兒網企業級監控平臺-Watcher

2. 告警治理

2.1. 報警升級

報警升級分為提醒升級和聯絡人升級,我們的報警升級沒有強制聯絡人向上升級,但使用者可以方便的在樹節點上設定聯絡人(一般在樹節點上設定相關負責人),樹節點上設定的聯絡人,其子節點上的告警都會接收到,而且是前面的聯絡人都沒人處理告警的時候(比如沒有接聽告警電話),才會通知樹節點聯絡人, 因此利用這種形式做聯絡人升級。

提醒升級是當一個報警開始傳送告警通知時,一開始我們只會傳送 Qtalk 提醒,Qtalk 屬於弱提醒,但如果過了一段時間這個報警仍然沒有人處理,就會升級成電話提醒,電話提醒則是屬於強提醒。

去哪兒網企業級監控平臺-Watcher

升級模板配置

去哪兒網企業級監控平臺-Watcher

2.2. 報警降噪

當配置的告警越來越多,很多告警都不是重要的告警,經過幾輪人員更替後,這些告警都會成為極大的噪音,當它報警後,新來的同學不清楚這個告警是監控的什麼東西,也不敢隨便處理比如關閉告警,於是放任不管,那這些報警就會一直報著,長時間的沒有人來出來。時間長了很容易引起相關人麻痺,導致錯失重要告警的處理。針對這種情況,我們開發了降噪演算法,演算法只根據報警開始時間和設定的報警間隔,來計算出當前是否處於傳送視窗,只有在傳送視窗期,告警通知才能真的傳送出去,否則不傳送通知。以此達到的效果是 比如:當一個告警設定通知間隔是5分鐘,但是持續了30分鐘還沒有人處理,那麼我們會動態拉伸他的通知間隔,邏輯上將通知間隔變成了10分鐘,1個小時沒人處理則變成20分鐘等等依次類推,這個告警持續時間越長,那麼通知視窗也會被拉的越來越長,通知的頻率就會越來越低,即便是他處在告警中。

去哪兒網企業級監控平臺-Watcher

2.3. 閃報抑制

在 Qunar,一個報警持續時間小於5分鐘的報警我們稱為閃報。很多時候我們剛開始配置報警時,尤其是一個新的報警,大家可能對閾值估算不準,或者由於很早之前配置的報警,之前設定的閾值已經跟現在的業務波動不太匹配了,就會導致報警波動、閃報。這種閃報通常來說不影響業務,但是頻繁打擾會導致報警接收人麻木。因此抑制的目的就是減少無意義的打擾,儘可能提升報警的精準性。

當前報警抑制的實現方式是觀察一個報警一段時間內報警狀態改變的頻率,如果頻率高於某一個點(這個閾值點是系統根據演算法算出並預設提供的,使用者可以自己修改)則會進入抑制狀態,頻率低於某一個點則會退出抑制狀態。其中半個小時內的狀態多次改變則狀態權重遞增。

閃報抑制配置:

去哪兒網企業級監控平臺-Watcher

2.4. 報警收斂

當某一個時刻突然出現了大量告警,這會導致告警刷屏,在去看 Qtalk 告警訊息時,根本就看不過來,一些重點的告警會被淹沒掉,或者根本無法確定哪個告警最有可能是需要重點關注的。在這些告警裡一定會有一些告警是因為其他告警造成的,比如一臺宿主當機,主機上的 load、disk 等告警都會報出來,甚至可能影響到業務指標,導致某個業務指標告警。所以報警之間會有一個隱形的依賴,通常主機或機房層面的告警依賴非常清晰,屬於物理依賴,而應用之間也有依賴,應用之間的告警就是邏輯依賴。

所以在做告警收斂時,依賴拓撲是很重要的,物理依賴可以很簡單的計算或者定義出來,而多應用間依賴在 Qunar 可以透過 Qtrace 來拿到依賴拓撲,因此目前在 Qunar 當某一時刻出現大量告警時,會觸發告警收斂,告警收斂會先在 Appcode 內收斂,根據依賴拓撲一層層收斂,AppCode 內收斂完成之後會進行 AppCode 間收斂,最終只會將葉子告警傳送通知,其他的只在詳情頁展示,並不真實傳送通知。

這裡面有一個難點,就是 AppCode 內配置的多個業務告警怎麼拿到依賴關係(依賴樹),目前 Qunar 將 Metrics 和 Qtrace 進行了結合,Qtrace 在記錄方法間呼叫時如果經過的方法內有記錄 Metric,那麼會將這個 Metric 資訊帶入到 Trace 資訊裡,最後經過洗數分析就能拿到指標間的依賴關係,根據指標間的依賴關係就能拿到告警的依賴關係。比如 一個 http 的入口方法  foo,此方法裡記錄了一個指標就是  foo.access.time,foo 呼叫了 bar 業務層方法,bar 業務層方法內記錄了一個指標 bar.exec.time,那麼指標  foo.access.time 就可以認為依賴 bar.exec.time,如果foo.access.time 和 bar.exec.time 同時告警,那麼只有bar.exec.time 的告警會通知出去。

去哪兒網企業級監控平臺-Watcher

3. Trace結合

Qtracer 是 Qunar 自研的 Trace 系統, Qtracer 首先是一個全鏈路追蹤系統,可以用來定位跨系統的各種問題;另外,透過收集鏈路中的各種資料達到應用效能管理(APM)的目的。而監控就是透過 Qtracer 收集鏈路資料的特性來做到跟 Qtracer 結合的。

首先 Qtracer 提供了 QTracer.mark() 方法,此方法能夠將自己想要的資訊關聯進當前 trace 的 context 中, 然後在我們自研的 Qmonitor agent 中,在記錄指標資料時呼叫  mark 方法,將當前指標標記進當前的 Trace 資訊裡面(如果當前有 Trace 資訊的話),以此能達到的效果就是一個帶著 Trace 資訊的請求從入口進來(如果沒有攜帶 Trace 資訊,可以生成 Trace),經過了 foo() 方法,而 foo 方法中記錄了指標 foo.access.time,那麼 foo.access.time 指標會被 mark 到當前 Trace 資訊中。

資料被 mark 進來後,當前會以日誌的形式落盤,然後經過洗數,最後會將 Trace 的 Trace Id 和當時經過的 Metric Name 的關聯資訊存入到 ElasticSearch 中便於後期檢索使用。

當這些資料資訊都沒有問題的時候,此時比如我們在  foo.access.time 指標上加了一個告警,一旦指標告警,我們就可以檢索出告警的這一段時間內所有的 Trace 資訊,透過 Trace 資訊能夠快速的反應出當時請求的狀態,以此來協助開發或應用 Owner 快速定位問題。

下圖是在 Watcher 上拉取當前告警時間段的 Trace Id 資訊:

去哪兒網企業級監控平臺-Watcher

點選 Trace Id 可以檢視具體的 Trace 資訊,以及呼叫拓撲等。

去哪兒網企業級監控平臺-Watcher

三、雲原生時代監控平臺的演進

2021年時,去哪兒網在公司內部進行了大規模容器化部署,到目前為止去哪兒網大部分的應用都已經執行在內部的多個 Kubernetes 叢集上。在這樣一個背景下早期我們許多根據 kvm 特性的相關設計也要跟著變化,比如容器跟 kvm 最大的一個變化便是動態 IP 問題,kvm 的主機一旦申請後IP 是固定的,且 kvm 主機的生命週期遠遠長於容器,通常是跟 AppCode 同生命週期,而容器生命週期則非常短,每一次變更釋出都會導致容器 IP 變化,這種頻繁變化給周邊系統帶來了許多問題,因此周邊系統也需要進行改造以應對這種變化。

1. 業務指標資料採集

Qmonitor 是 Watcher 的資料採集模組,雖然 Prometheus 有自己的 Client,但是想要讓全公司的應用從Qmonitor 改成 Prometheus Client 顯然不現實。而Qmonitor 早期設計是針對 kvm 的流程設計的,比如使用者在透過 Qmonitor 監控時我們自動拿到對應的需要監控的主機名或 IP,然後透過 Pull 當前主機對應的 url 才能拿到監控資料。而容器的 IP 是經常變化的,因此我們修改流程,增加了 Discovery 的功能。

首先我們增加了事件監聽器,用來監聽和收集所有 k8s 叢集的事件,然後將這些事件儲存到 DB 的同時傳送到 mq中,其他應用可以監聽 mq 來拿到自己想要的事件。然後在 qmonitor 增加 client-discovery 模組,此模組可以監聽對應的訊息事件,然後動態的更替對應的 ip 和 meta 資訊,更新的資料提供給 qmonitor server來使用。這樣便能動態的發現和變更對應的 client 地址,而且對業務無感知。

去哪兒網企業級監控平臺-Watcher

2. 基礎設施層監控

雲原生時代,我們的基礎設施層由 kvm 雲變成了容器雲, kvm 時我們使用的 collectd 來收集基礎設施相關的監控指標,比如 cpu、磁碟資料。collectd 是一個 agent 需要安裝在 kvm server 上,但是容器內通常只有一個程式,agent 的形式是不友好的。而 k8s 層的相關監控我們使用  prometheus+cAdvisor,k8s 自身便是使用 prometheus client 來 export 內部的狀態資料再配合使用 cAdvisor 監控容器執行時的狀態資料比如 cpu、記憶體。

2.1 融合Prometheus

我們的 Dashboard 是根據 Grafana 做的二次開發,而 Grafana 本身就支援很多的資料來源外掛,其中便包括 Prometheus,因此能夠很方便的將 Prometheus 跟 Watcher 進行融合,整合後依然提供對用的 Pod 模板檢視,允許使用者直接透過自己的 AppCode 就能檢視到自身應用下當前的 pod 狀態,以及應用級的 pod 狀態。

去哪兒網企業級監控平臺-Watcher

2.2 容器告警

容器的告警像 kvm 一樣,也支援模板化,容器透過監聽事件來將模板應用到對應 AppCode 上實現動態新增告警,模板包括了檢測指標、檢測規則、告警閾值等資訊。由於 Prometheus 自身支援異常檢測,因此可直接將告警規則透過 prometheus crd 同步到 prometheus,透過配置, Prometheus 檢測到異常後,會將異常資訊 Push 到 我們自研的 Alert-API 模組,Alert-API 可以說是 prometheus  到 icinga 的一個轉換器,Icinga 是我們真正的告警管理模組,支援開關報警、告警升級等策略,Icinga 類似 Nagios,但是 icinga 提供了更友好的 API 操作入口。

去哪兒網企業級監控平臺-Watcher

四、未來規劃

Metrics 的資料是比較簡潔和標準的,所以我們很容易從宏觀層面上觀測分析和判斷它正常與否,斷言 Metrics 的成本也相對較低,但是想要定位真正的根因,還要藉助 Trace、Log 的資料,比如透過 metrics 你只能發現現在系統處於一種異常狀態,但到底是程式碼 Bug 還是什麼原因造成的,就需要更詳細的資訊輸入,而這些資訊是 Trarce 和 Log 或者其他維度的資料提供的。因此接下來 Watcher 系統也會嘗試融合 Trace、Log 以及更多維度的資料比如事件,其實從上面可以看到,Watcher 已經開始與 Trace 進行了融合,我們目前的方式是透過報警的 metrics 關聯到 trace,如果指標發生異常了就能精確的檢索出跟這個異常指標相關的 trace 資訊,就能精確定位到哪些 trace 可能是有問題的,而更多的場景還需要我們去挖掘,目前業界也都在向這個方向演進。

關於智慧監控部分,2022年底 Qunar 內部落地了根因分析系統,目前與 Watcher 的報警系統進行了聯動,當出現告警時根因分析自動監聽到告警事件,嘗試從鏈路 Trace、日誌、事件、中介軟體、執行時、物理拓撲探索等維度進行關聯分析最終將報告推送給使用者,以此輔助使用者快速定位問題。而動態異常檢測雷達也還在落地中,用於彌補部分不易使用靜態閾值斷言的指標的異常檢測。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2948627/,如需轉載,請註明出處,否則將追究法律責任。

相關文章