我的新課《C2C 電商系統微服務架構120天實戰訓練營》在公眾號儒猿技術窩上線了,感興趣的同學,可以長按掃描下方二維碼了解課程詳情:
課程大綱請參見文末
之前,寫過幾篇有關線上問題排查的文章,文中附帶了一些監控圖,有些讀者對此很感興趣,問我監控系統選型上有沒有好的建議?
圖片來自 Pexels
目前我所經歷的幾家公司,監控系統都是自研的。其實業界有很多優秀的開源產品可供選擇,能滿足絕大部分的監控需求,如果能從中選擇一款滿足企業當下的訴求,顯然最省時省力。
這篇文章,我將對監控體系的基礎知識、原理和架構做一次系統性整理,同時還會對幾款最常用的開源監控產品做下介紹,以便大家選型時參考。
內容包括如下三部分:
必知必會的監控基礎知識
主流監控系統介紹
監控系統俗稱「第三隻眼」,幾乎是我們每天都會打交道的系統,下面四項基礎知識我認為是必須要了解的。
正所謂「無監控,不運維」,監控系統的地位不言而喻。不管你是監控系統的開發者還是使用者,首先肯定要清楚:監控系統的目標是什麼?它能發揮什麼作用?監控系統有如下七大作用:
實時採集監控數據:包括硬體、作業系統、中間件、應用程式等各個維度的數據。
實時反饋監控狀態:通過對採集的數據進行多維度統計和可視化展示,能實時體現監控對象的狀態是正常還是異常。
預知故障和告警:能夠提前預知故障風險,並及時發出告警信息。
輔助定位故障:提供故障發生時的各項指標數據,輔助故障分析和定位。
輔助性能調優:為性能調優提供數據支持,比如慢 SQL,接口響應時間等。
輔助容量規劃:為伺服器、中間件以及應用集群的容量規劃提供數據支撐。
輔助自動化運維:為自動擴容或者根據配置的 SLA 進行服務降級等智能運維提供數據支撐。
出任何線上事故,先不說其他地方有問題,監控部分一定是有問題的。聽著很甩鍋的一句話,仔細思考好像有一定道理。我們在事故復盤時,通常會思考這三個和監控有關的問題:有沒有做監控?
監控是否及時?
監控信息是否有助於快速定位問題?
可見光有一套好的監控系統還不夠,還必須知道如何用好它。一個成熟的研發團隊通常會定一個監控規範,用來統一監控系統的使用方法。
如何使用監控系統?總結如下四個方面:
了解監控對象的工作原理:要做到對監控對象有基本的了解,清楚它的工作原理。比如想對 JVM 進行監控,你必須清楚 JVM 的堆內存結構和垃圾回收機制。
確定監控對象的指標:清楚使用哪些指標來刻畫監控對象的狀態?比如想對某個接口進行監控,可以採用請求量、耗時、超時量、異常量等指標來衡量。
定義合理的報警閾值和等級:達到什麼閾值需要告警?對應的故障等級是多少?不需要處理的告警不是好告警,可見定義合理的閾值有多重要,否則只會降低運維效率或者讓監控系統失去它的作用。
建立完善的故障處理流程:收到故障告警後,一定要有相應的處理流程和 oncall 機制,讓故障及時被跟進處理。
監控已然成為了整個產品生命周期非常重要的一環,運維關注硬體和基礎監控,研發關注各類中間件和應用層的監控,產品關注核心業務指標的監控。可見,監控的對象已經越來越立體化。這裡,我對常用的監控對象以及監控指標做了分類整理,供大家參考:
包括:電源狀態、CPU 狀態、機器溫度、風扇狀態、物理磁碟、raid 狀態、內存狀態、網卡狀態。②伺服器基礎監控
CPU:單個 CPU 以及整體的使用情況。
內存:已用內存、可用內存。
磁碟:磁碟使用率、磁碟讀寫的吞吐量。
網絡:出口流量、入口流量、TCP 連接狀態。
包括:資料庫連接數、QPS、TPS、並行處理的會話數、緩存命中率、主從延時、鎖狀態、慢查詢。Nginx:活躍連接數、等待連接數、丟棄連接數、請求量、耗時、5XX 錯誤率。
Tomcat:最大線程數、當前線程數、請求量、耗時、錯誤量、堆內存使用情況、GC 次數和耗時。
緩存:成功連接數、阻塞連接數、已使用內存、內存碎片率、請求量、耗時、緩存命中率。
消息隊列:連接數、隊列數、生產速率、消費速率、消息堆積量。
HTTP 接口:URL 存活、請求量、耗時、異常量。
RPC 接口:請求量、耗時、超時量、拒絕量。
JVM:GC 次數、GC 耗時、各個內存區域的大小、當前線程數、死鎖線程數。
線程池:活躍線程數、任務隊列大小、任務執行耗時、拒絕任務數。
連接池:總連接數、活躍連接數。
日誌監控:訪問日誌、錯誤日誌。
業務指標:視業務來定,比如 PV、訂單量等。
無論是開源的監控系統還是自研的監控系統,監控的整個流程大同小異。數據採集:採集的方式有很多種,包括日誌埋點進行採集(通過 Logstash、Filebeat 等進行上報和解析),JMX 標準接口輸出監控指標,被監控對象提供 REST API 進行數據採集(如 Hadoop、ES),系統命令行,統一的 SDK 進行侵入式的埋點和上報等。
數據傳輸:將採集的數據以 TCP、UDP 或者 HTTP 協議的形式上報給監控系統,有主動 Push 模式,也有被動 Pull 模式。
數據存儲:有使用 MySQL、Oracle 等 RDBMS 存儲的,也有使用時序資料庫 RRDTool、OpentTSDB、InfluxDB 存儲的,還有使用 HBase 存儲的。
數據展示:數據指標的圖形化展示。
監控告警:靈活的告警設置,以及支持郵件、簡訊、IM 等多種通知通道。
先來了解下 Zabbix 的架構設計:
Zabbix Server:核心組件,C 語言編寫,負責接收 Agent、Proxy 發送的監控數據,也支持 JMX、SNMP 等多種協議直接採集數據。同時,它還負責數據的匯總存儲以及告警觸發等。
Zabbix Proxy:可選組件,對於被監控機器較多的情況下,可使用 Proxy 進行分布式監控,它能代理 Server 收集部分監控數據,以減輕 Server 的壓力。
Zabbix Agentd:部署在被監控主機上,用於採集本機的數據並發送給 Proxy 或者 Server,它的插件機制支持用戶自定義數據採集腳本。
Agent 可在 Server 端手動配置,也可以通過自動發現機制被識別。數據收集方式同時支持主動 Push 和被動 Pull 兩種模式。
Database:用於存儲配置信息以及採集到的數據,支持 MySQL、Oracle 等關係型資料庫。同時,最新版本的 Zabbix 已經開始支持時序資料庫,不過成熟度還不高。
Web Server:Zabbix 的 GUI 組件,PHP 編寫,提供監控數據的展現和告警配置。
產品成熟:由於誕生時間長且使用廣泛,擁有豐富的文檔資料以及各種開源的數據採集插件,能覆蓋絕大部分監控場景。
採集方式豐富:支持 Agent、SNMP、JMX、SSH 等多種採集方式,以及主動和被動的數據傳輸方式。
較強的擴展性:支持 Proxy 分布式監控,有 Agent 自動發現功能,插件式架構支持用戶自定義數據採集腳本。
配置管理方便:能通過 Web 界面進行監控和告警配置,操作方便,上手簡單。
性能瓶頸:機器量或者業務量大了後,關係型資料庫的寫入一定是瓶頸,官方給出的單機上限是 5000 臺,個人感覺達不到,尤其現在應用層的指標越來越多。雖然最新版已經開始支持時序資料庫,不過成熟度還不高。
應用層監控支持有限:如果想對應用程式做侵入式的埋點和採集(比如監控線程池或者接口性能),Zabbix 沒有提供對應的 SDK,通過插件式的腳本也能曲線實現此功能,個人感覺 Zabbix 就不是做這個事的。
數據模型不強大:不支持 Tag,因此沒法按多維度進行聚合統計和告警配置,使用起來不靈活。
方便二次開發難度大:Zabbix 採用的是 C 語言,二次開發往往需要熟悉它的數據表結構,基於它提供的 API 更多只能做展示層的定製。
Open-falcon 是小米 2015 年開源的企業級監控工具,採用 Go 和 Python 語言開發,這是一款靈活、高性能且易擴展的新一代監控方案,目前小米、美團、滴滴等超過 200 家公司在使用它。小米初期也使用的 Zabbix 進行監控,但是機器量和業務量上來後,Zabbix 就有些力不從心了。因此,後來自主研發了 Open-Falcon,在架構設計上吸取了 Zabbix 的經驗,同時很好地解決了 Zabbix 的諸多痛點。先來了解下 Open-Falcon 的架構設計:
Falcon-agent:數據採集器和收集器,Go 開發,部署在被監控的機器上,支持3種數據採集方式。
首先它能自動採集單機 200 多個基礎監控指標,無需做任何配置;同時支持用戶自定義的 Plugin 獲取監控數據;此外,用戶可通過 HTTP 接口,自主 Push 數據到本機的 proxy-gateway,由 Gateway 轉發到 Server。
Transfer:數據分發組件,接收客戶端發送的數據,分別發送給數據存儲組件 Graph 和告警判定組件 Judge,Graph 和 Judge 均採用一致性 Hash 做數據分片,以提高橫向擴展能力。同時 Transfer 還支持將數據分發到 OpenTSDB,用於歷史歸檔。
Graph:數據存儲組件,底層使用 RRDTool(時序資料庫)做單個指標的存儲,並通過緩存、分批寫入磁碟等方式進行了優化。據說一個 Graph 實例能夠處理 8W+ 每秒的寫入速率。
Judge 和 Alarm:告警組件,Judge 對 Transfer 組件上報的數據進行實時計算,判斷是否要產生告警事件,Alarm 組件對告警事件進行收斂處理後,將告警消息推送給各個消息通道。
API:面向終端用戶,收到查詢請求後會去 Graph 中查詢指標數據,匯總結果後統一返回給用戶,屏蔽了存儲集群的分片細節。
自動採集能力:Falcon-agent 能自動採集伺服器的 200 多個基礎指標(比如 CPU、內存等),無需在 Server 上做任何配置,這一點可以秒殺 Zabbix。
強大的存儲能力:底層採用 RRDTool,並且通過一致性 Hash 進行數據分片,構建了一個分布式的時序數據存儲系統,可擴展性強。
靈活的數據模型:借鑑 OpenTSDB,數據模型中引入了 Tag,這樣能支持多維度的聚合統計以及告警規則設置,大大提高了使用效率。
插件統一管理:Open-Falcon 的插件機制實現了對用戶自定義腳本的統一化管理,可通過 HeartBeat Server 分發給 Agent,減輕了使用者自主維護腳本的成本。
個性化監控支持:基於 Proxy-gateway,很容易通過自主埋點實現應用層的監控(比如監控接口的訪問量和耗時)和其他個性化監控需求,集成方便。
整體發展一般:社區活躍度不算高,同時版本更新慢,有些大廠是基於它的穩定版本直接做二次開發的,關於以後的前景其實有點擔憂。
UI 不夠友好:對於業務線的研發來說,可能只想便捷地完成告警配置和業務監控,但是它把機器分組、策略模板、模板繼承等概念全部暴露在 UI 上,感覺在圍繞這幾個概念設計 UI,理解有點費勁。
安裝比較複雜:個人的親身感受,由於它是從小米內部衍生出來的,雖然去掉了對小米內部系統的依賴,但是組件還是比較多,如果對整個架構不熟悉,安裝很難一蹴而就。
Prometheus(普羅米修斯)是由前 Google 員工 2015 年正式發布的開源監控系統,採用 Go 語言開發。它不僅有一個很酷的名字,同時它有 Google 與 K8s 的強力支持,開源社區異常火爆。Prometheus 於 2016 年加入雲原生基金會,是繼 K8s 後託管的第二個項目,未來前景被相當看好。它和 Open-Falcon 最大不同在於:數據採集是基於 Pull 模式的,而不是 Push 模式,並且架構非常簡單。先來了解下 Prometheus 的架構設計:
Prometheus Server:核心組件,用於收集、存儲監控數據。它同時支持靜態配置和通過 Service Discovery 動態發現來管理監控目標,並從監控目標中獲取數據。
此外,Prometheus Server 也是一個時序資料庫,它將監控數據保存在本地磁碟中,並對外提供自定義的 PromQL 語言實現對數據的查詢和分析。
Exporter:用來採集數據,作用類似於 Agent,區別在於 Prometheus 是基於 Pull 方式拉取採集數據的。
因此,Exporter 通過 HTTP 服務的形式將監控數據按照標準格式暴露給 Prometheus Server,社區中已經有大量現成的 Exporter 可以直接使用,用戶也可以使用各種語言的 client library 自定義實現。
Push gateway:主要用於瞬時任務的場景,防止 Prometheus Server 來 Pull 數據之前此類 Short-lived jobs 就已經執行完畢了,因此 Job 可以採用 Push 的方式將監控數據主動匯報給 Push gateway 緩存起來進行中轉。
Alert Manager:當告警產生時,Prometheus Server 將告警信息推送給 Alert Manager,由它發送告警信息給接收方。
Web UI:Prometheus 內置了一個簡單的 Web 控制臺,可以查詢配置信息和指標等,而實際應用中我們通常會將 Prometheus 作為 Grafana 的數據源,創建儀錶盤以及查看指標。
輕量管理:架構簡單,不依賴外部存儲,單個伺服器節點可直接工作,二進位文件啟動即可,屬於輕量級的 Server,便於遷移和維護。
較強的處理能力:監控數據直接存儲在 Prometheus Server 本地的時序資料庫中,單個實例可以處理數百萬的 Metrics。
靈活的數據模型:同 Open-Falcon,引入了 Tag,屬於多維數據模型,聚合統計更方便。
強大的查詢語句:PromQL 允許在同一個查詢語句中,對多個 Metrics 進行加法、連接和取分位值等操作。
很好地支持雲環境:能自動發現容器,同時 K8s 和 Etcd 等項目都提供了對 Prometheus 的原生支持,是目前容器監控最流行的方案。
通過上面的介紹,大家對主流的監控系統應該有了一定的認識。先明確清楚你的監控需求:要監控的對象有哪些?機器數量和監控指標有多少?需要具備什麼樣的告警功能?
監控是一項長期建設的事情,一開始就想做一個 All In One 的監控解決方案,我覺得沒有必要。從成本角度考慮,在初期直接使用開源的監控方案即可,先解決有無問題。
從系統成熟度上看,Zabbix 屬於老牌的監控系統,資料多,功能全面且穩定,如果機器數量在幾百臺以內,不用太擔心性能問題,另外,採用資料庫分區、SSD 硬碟、Proxy 架構、Push 採集模式都可以提高監控性能。
Zabbix 在伺服器監控方面佔絕對優勢,可以滿足 90% 以上的監控場景,但是應用層的監控似乎並不擅長,比如要監控線程池的狀態、某個內部接口的執行時間等,這種通常都要做侵入式埋點。相反,新一代的監控系統 Open-Falcon 和 Prometheus 在這一點做得很好。
從整體表現上來看,新一代監控系統也有明顯的優勢,比如:靈活的數據模型、更成熟的時序資料庫、強大的告警功能,如果之前對 Zabbix 這種傳統監控沒有技術積累,建議使用 Open-Falcon 或者 Prometheus。
Open-Falcon 的核心優勢在於數據分片功能,能支撐更多的機器和監控項;Prometheus 則是容器監控方面的標配,有 Google 和 K8s 加持。
Zabbix、Open-Falcon 和 Prometheus 都支持和 Grafana 做快速集成,想要美觀且強大的可視化體驗,可以和 Grafana 進行組合。
用合適的監控系統解決相應的問題即可,可以多套監控同時使用,這種在企業初期很常見。
到中後期,隨著機器數據增加和個性化需求增多(比如希望統一監控平臺、打通公司的 CMDB 和組織架構關係),往往需要二次開發或者通過監控系統提供的 API 做集成,從這點來看,Open-Falcon 或者 Prometheus 更合適。
如果非要自研,可以多研究下主流監控系統的架構方案,借鑑它們的優勢。
本文對監控體系的基礎知識、原理和主流架構做了詳細梳理,希望有助於大家對監控系統的認識,以及在技術選型時做出更合適的選擇。
END