微店分布式監控系統實踐

為什么我們要造一套輪子

早期我們和很多公司一樣使用的是zabbix監控, 應該說zabbix的功能還是蠻強大的。但是隨著公司的業務發展,我們很快發現有很多問題zabbix很難解決。

問題主要提現在幾個方面:第一,協作的問題,zabbix界面設計非常晦澀難懂,更多是站在運維的角度設計,和時下流行的devops理念顯得格格不入,我們希望開發能更多參與進來,而現狀是只有運維在配置 zabbix;第二,隨著服務化的推進,調用關系越來越復雜,問題診斷定位也越來越困難,光報警出來還不夠,還要能夠快速的定位問題根源;第三,配置繁瑣,配置一些簡單的系統指標問題還不大,但在虛擬化、容器、服務化等理念深入人心的現在,監控指標開始呈爆炸式的增長,配置zabbix不但需要較高的水平,更需要堅韌的毅力。

基于以上問題,剛開始我們圍繞著zabbix并結合cmdb的服務樹做了一些二次開發,但還是慢慢發現越來越感到力不從心,而且也滿足不了我們的需求,所以我們決定做一個我們自己的監控系統。

如何將監控系統落地

zabbix雖然并不好用,但功能非常強大,涵蓋了大部分的監控需求,在短期內我們難以造一個輪子完全取代zabbix,而且閉門造輪子,不快速上線快速試錯,我們很難真正將這個輪子造好。

我們在規劃新的監控系統之初,有一個共識,覺得大多數問題都是能通過日志記錄下來,并可以通過日志監控去發現,所以首先搞定對日志的監控就能覆蓋絕大多數的監控場景,這塊恰恰又是zabbix在devops理念下薄弱的地方。在搞定日志監控后,再去完善zabbix 已有的功能就能從線上慢慢移除對于zabbix的依賴。

項目從16年4月份開始寫下第一行代碼,到現在歷時半年多,經歷了多個重大版本的迭代,從最開始簡單的日志處理系統逐漸成長為一個覆蓋各種場景的全功能監控系統,將上百個服務都納入監控范疇,系統指標超過10W個,日志指標超過1萬個,報警也超過了萬次。 這個發展歷程也非常符合我們當初對于監控系統的定位。

現有的功能點

操作維護簡單

  1. 按照產品樹組織的dashboard,查看和配置更加容易,開發和運維都可以操作。

  2. 與cmdb結合,不需要額外維護應用,機器,人員,角色信息。

  3. agent節點自發現,自動推送任務。

  4. 支持監控任務自發現。

  5. 支持自定監控模板和自發現模板。整套監控系統經過半年的開發,已經完成系統監控、JVM 監控、日志監控、ES 數據監控、網絡監控等重要的功能,我們的目標是將整個系統打造成一個強大的全功能監控體系,還有工作等待我們去完善。

監控指標類型

  1. 應用監控支持外部方式監控日志,也支持java應用通過 sdk 生成指標。

  2. jvm 監控。

  3. 大部分常用的系統監控指標。

  4. http/https 方式監控,特別的是支持了text,xpath,jsonpath方式解析響應體。

日志監控

  1. 支持對日志的字段解析和多種指標聚合方式。

  2. 支持日志的實時采集,不再需要額外手動部署flume或者logstash,方便與kafka,elk生態打通。

報警及診斷

  1. 同時支持多種報警方式(郵件、短信、微信、電話)。

  2. 指標報警、日志異常、調用鏈跟蹤三者關聯,快速定位問題。

架構設計

存儲層:我們利用graphite(carbon,whisper) 來存儲我們的時序數據,利用 mysql 來存儲任務信息和少量需要分析的異常日志。

集群路由:我們設計了一個單獨的路由器,用于切割集群成為不同的集群,例如測試集群、預發集群和線上集群,路由器也方便我們設計無狀態的組件,每個組件不需要附帶任何信息,只需要啟動的時候訪問路由器便能知道自己屬于哪個集群。

zookeeper:我們依賴zookeeper 來實現服務發現和集群選主的功能。

設計理念

日志:在設計整個監控的時候,我們的架構都圍繞著日志而設計,我們關心如何處理日志,如何提取日志中的指標,如何對指標作聚合,如何報警,報警之后如何提煉出日志的關鍵詞。應用異常、業務數據、性能指標甚至內核參數都能從日志中著手監控,圍繞著日志,我們已經能覆蓋 80% 的監控場景。

服務化:作為服務化治理的工具,監控系統本身也應該服務化,我們將控制臺、聚合器、檢查器等重要組件都設計成獨立的服務,這方便了日后的開發和維護,同時當我們想加功能的時候,也可以將新功能作為一個獨立的服務加入到整個系統里,不破壞原有的功能模塊。

高可用和自監控:監控系統作為獨立的系統,也需要能夠對自身做監控,例如對于各個組件做健康檢查,每個組件在設計部署的時候也要考慮到高可用的問題,不能存在單點的問題。

我們趟過的河

1. 如何提取日志的指標

我們為日志設計了一套正則處理機制,將日志中的指標分為幾種類型:

  • Count 指標,只要被正則匹配,就為該指標加一,這是最常用的類型,對于 exception 等關鍵字非常有用。

  • Max/Min/Avg 類型,在一段時間(通常為一分鐘)范圍內,統計某個浮點型的數據的最大值,最小值或平均值,對于監控例如 sql 語句的慢查詢非常有效。

  • Map 類型,可以累加 Count/Max/Min/Avg 等類型,對于不確定指標 Key 的情況,利用 Map 可以自動產生指標名稱,利用在日志里出現又被正則命中的關鍵字作為 Key。

例如我們做異常監控,可以將 Exception 作為關鍵字,選擇 Count 類型,每當出現 Exception, log.exception 指標就加一并立即報警。

2. 如何打通指標、日志內容和鏈路關系

我們在配置日志指標的時候可以配置一個特殊的指標,當日志符合這個特殊指標的時候,agent 會同時提取這行日志并連同指標發送出去,聚合器在聚合指標的同時并把這些日志存儲起來。

這些日志里通常都存有 trace id,這是報警和鏈路關系的關鍵所在。鏈路跟蹤系統(在微店稱為 vtrace)的 sdk 會在日志拋出異常的時候將 trace id 也打印在日志里,一個 trace id 和一個完整的鏈路請求一一對應,它記錄著這個請求經過了哪些服務,每個服務的上下游狀態和耗時。

當發生故障的時候,檢查器會快速將這些日志查詢出來,并對于日志里的 trace id 和關鍵字進行分析,根據關鍵字我們能快速地知道故障的直接原因,根據 trace id 能快速知道整個鏈路的故障原因。

3. 日志如何去重

當故障發生的時候,如果關聯日志較少,提取關鍵字還比較容易,但如果日志有成千上萬條,提取關鍵字就顯得不那么容易。我們借鑒搜索引擎處理文本的辦法,利用 simhash 和海明距離幫助我們準確地定位關鍵字。 每個日志可能有不同的時間戳、IP,但其實他們都是類似的,我們先利用 simhash 計算每條日志的哈希值,并利用海明距離判定兩條日志是否相似,海明距離在 3 以下的日志,我們就認為他們是同一條日志。 標記每種日志的出現次數,對他們進行排序,我們再對 top 10 的日志抓取關鍵字和 trace id。

simhash 對于中長日志的效果較好,特別是對于帶堆棧的日志,但小日志因為文本少,誤差會較大,如果有需要對短日志做相似匹配,建議自己設計算法提取文本的特征值。

4. 如何設計 agent 結構

我們從穩定、可運維性、安全幾個角度做了一些設計:

  • 單 Master 多 Worker 結構,我們將 Agent 設計成了多進程的模式,Master 功能非常單一,只負責和控制臺通信以及維護 Worker 的啟動狀態和版本,當 Master 啟動的時候,控制臺會告知 Master 需要啟動的 Worker 列表以及版本,但 Worker 不存在或是版本過舊,Master 會拉取最新的文件,然后啟動,并監聽 Worker 的管道,一旦 Worker 因為某些原因掛掉,Master 會重啟它。

  • 自升級和灰度發布,每次 Agent 升級都是一次大型的發布,而一旦發布出問題,往往會焦頭爛額,所以我們為 Agent 的升級設計了灰度機制,我們可以精確地升級某臺機子的 Agent 版本或是某個網段某個分組的 Agent,以方便我們測試某個功能或是檢查是否有兼容問題。

  • 雙向通信,控制臺在有新的監控任務的時候,需要主動將任務推送到 Agent,因為大部分的 rpc 框架都是單向通信,所以傳統的做法是讓 Agent 也開一個端口,利用兩條 rpc 連接來達到目的。但我們覺得這個方式不利于擴展,碰到多層網絡結構就歇菜了,況且 tcp 本身就是全雙工的連接,兩個連接顯得多此一舉,為此我們在 tcp 的基礎上利用 protobuf 重新封裝了一個雙工的 rpc 協議。

  • 資源控制,Agent 作為監控系統的一部分,首要限制就是不能影響正常的業務,不能和業務進程爭搶 CPU、內存和網卡等重要系統資源。Agent 在解析日志的時候會判斷任務的資源使用率,自動拋棄過大的日志并作報警。

成果

在經過半年的使用后,我們的監控比起原先的 zabbix 有長足的進步:

  1. 依靠日志監控和自發現,現在每上線一個服務,都自動對服務的異常日志、中間件日志做監控,一旦服務某個功能有問題,立刻報警提醒開發和運維關注。

  2. 每次報警之后,監控系統立刻對此次報警作分析,根據相關的日志提取關鍵字和鏈路信息,在第一時間將分析結果發送到開發和運維的手中,我們將問題的排查時間從原來的數小時縮短到幾分鐘。

  3. 精心設計的 dashboard 和任務面板完整地呈現服務樹的關系,并把每個服務的 metric 都羅列出來,在 metric 過多的時候,還可以通過關鍵字進行搜索,開發和運維登錄監控系統的頻次比以前高出很多。

  4. 通過對日志中業務指標的提取,監控系統也覆蓋到了大部分重要的業務監控,利用環比進行業務指標曲線的監控。對于無法從日志中提取的業務指標,例如使用 Elasticsearch 來存儲數據的一些業務,我們也同樣設計了一個服務將 Elasticsearch 的數據轉化為時序數據并進行監控。

展望

整套監控系統經過半年的開發,已經完成系統監控、JVM 監控、日志監控、ES 數據監控、網絡監控等重要的功能,我們的目標是將整個系統打造成一個強大的全功能監控體系,還有工作等待我們去完善。 例如我們的 Agent 雖然是多進程結構,但對于 worker 的控制還不夠完善,無法支持自定義腳本的監控,我們還需要改造 master 做更靈活的控制。最后,如果你對打造監控系統或者其他技術崗位感興趣,歡迎加入我們。 

 

來自:http://mp.weixin.qq.com/s/QIdbIcURkiU3L01cF3nPdw

 

 本文由用戶 dhphmm 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!