基於Prometheus的微服務監控實踐

基於Prometheus的微服務監控實踐

以下基於網易雲的實戰

在過去數年裡,微服務的落地一直都是業界重點關注的問題。與傳統監控相比,微服務監控面臨著更多難點。這篇文章詳細介紹了網易雲輕舟微服務平臺是如何做監控的。

當監控遇上微服務

在過去數年裡,微服務的落地一直都是業界重點關注的問題,其始終面臨著部署、監控、配置和治理等方面的挑戰。輕舟微服務平臺是網易云為企業提供的一套微服務解決方案,其中微服務監控是其關注的重點問題之一。與傳統監控相比,微服務監控面臨著更多難點,包括:

  1. 監控對象動態可變,無法進行預先配置;

  2. 監控範圍非常繁雜,各類監控難以互相融合;

  3. 微服務實例間的調用關係非常複雜,故障排查會很困難;

  4. 微服務架構仍在快速發展,難以抽象出穩定的通用監控模型。

在工程角度也面臨著不少考驗,如:

  • 在微服務架構裡,軟件系統通常會被拆分為數十甚至數百個微服務,這種拆分會使得監控數據爆炸增長,監控系統必須具備處理和展示這些數據的能力;

  • 監控系統必須要保證可靠性,具體而言:保證不會因為單點故障而全局失效,監控數據有備份機制,系統各服務的實例均可通過備份數據得到恢復;

  • 監控系統必須支持雲上部署及快速水平擴容,這既是雲原生的基本要求,也符合企業系統微服務化演進的實際情況。

微服務監控的技術選型

微服務監控的諸多挑戰使得我們不得不慎重地進行技術選型。選擇開源還是再造輪子,這個問題在項目初期一直困擾著我們,經過一段時間的調研和論證,開源項目 Prometheus 成了最終的答案。

Prometheus 是 CNCF 旗下的項目,該項目是一個用於系統和應用服務監控的軟件,它能夠以給定的時間間隔從給定目標中收集監控指標,並能夠通過特定查詢表達式獲取查詢結果。

選擇 Prometheus 的主要原因是:

靈活的數據模型:在 Prometheus 裡,監控數據是由值、時間戳和標籤表組成的,其中監控數據的源信息是完全記錄在標籤表裡的;同時 Prometheus 支持在監控數據採集階段對監控數據的標籤表進行修改,這使其具備強大的擴展能力;

強大的查詢能力:Prometheus 提供有數據查詢語言 PromQL。從表現上來看,PromQL 提供了大量的數據計算函數,大部分情況下用戶都可以直接通過 PromQL 從 Prometheus 裡查詢到需要的聚合數據;

健全的生態: Prometheus 能夠直接對常見操作系統、中間件、數據庫、硬件及編程語言進行監控;同時社區提供有 Java/Golang/Ruby 語言客戶端 SDK,用戶能夠快速實現自定義監控項及監控邏輯;

良好的性能

:在性能方面來看,Prometheus 提供了 PromBench 基準測試,從最新測試結果來看,在硬件資源滿足的情況下,Prometheus 單實例在每秒採集 10w 條監控數據的情況下,在數據處理和查詢方面依然有著不錯的性能表現;

更契合的架構:採用推模型的監控系統,客戶端需要負責在服務端上進行註冊及監控數據推送;而在 Prometheus 採用的拉模型架構裡,具體的數據拉取行為是完全由服務端來決定的。服務端是可以基於某種服務發現機制來自動發現監控對象,多個服務端之間能夠通過集群機制來實現數據分片。推模型想要實現相同的功能,通常需要客戶端進行配合,這在微服務架構裡是比較困難的;

成熟的社區:Prometheus 是 CNCF 組織第二個畢業的開源項目,擁有活躍的社區;成立至今,社區已經發布了一百多個 P 版本,項目在 GitHub 上獲得的 star 數超過了 2 萬。

Prometheus 雖然在上述六方面擁有優勢,但其仍然難以滿足微服務監控的所有需求,具體而言:

  1. 僅適用於維度監控,不能用於日誌監控、分佈式追蹤等範圍;

  2. 告警規則和告警聯繫人僅支持通過靜態文件配置;

  3. 原生支持的數據聚合函數有限且不支持擴展;

這些不足都說明了一個事實,Prometheus 社區版並非微服務監控的最終答案。

我們的答案 - 輕舟微服務監控系統

從大的方面來看,我們將微服務監控劃分為維度監控、日誌監控、分佈式追蹤等三部分。其中維度監控在整個微服務監控裡最為重要,所佔比例也最大,此類監控的層級有如下劃分:

  • 基礎設施監控: 主要對各個微服務實例所在的基礎設施進行監控,具體包括這些設施的運行狀態、資源使用情況及系統日誌進行監控,一般而言微服務應用實例會運行在容器裡,因此這個維度的監控對象也通常包含有容器編排系統、持續構建系統、鏡像倉庫等,這些對象的具體監控指標的範圍包括對象的健康狀態、運行狀態、資源使用情況等;

  • 微服務通用監控:主要針對微服務通用指標進行監控,包括服務實例處理請求的情況及實例調用其它服務的情況,具體而言包括請求總數、請求處理時延(中位數,包括有 90、95 和 99 值)、請求結果(成功、失敗、熔斷、限流、超時和拒絕)統計、調用其它服務的結果(成功、失敗、熔斷、限流、超時和拒絕)統計及時延(中位數,包括有 90、95 和 99 值);

  • 應用監控:主要對具體的微服務實例進行性能監控,通過數據自動化收集、數據可視化展示,使用戶能夠及時、全面地掌控各個實例的性能情況,定位性能瓶頸。這一維度重點在於提供豐富的應用性能展示及性能問題定位功能,包括應用響應時間、吞吐量和狀態的展示,慢響應和錯誤明細的查詢。

  • 通用中間件:我們沒有預置這個維度的監控到系統裡,不過得益於 Prometheus 完善的生態,系統保留有對常用數據庫、消息隊列及緩存進行監控的能力,具體包括 MySQL、Redis、Memcached、Consul、RabbitMQ 及 Kafka 等。

在工程實現方面,我們進行了如下設計:

  1. 用 Prometheus 原生的聯邦集群部署模式,使得全部監控數據分片處理;分片處理機制使得只需要增加實例個數就能夠應對海量監控數據問題;

  2. 多 Prometheus 實例作用於同一監控對象,使得單一實例失效也不會影響到此對象的監控,滿足高可用的要求;

  3. 監控系統所有組件及配置均實現容器化並由 Kubernetes 編排;理論上,在任意 Kubernetes 集群裡都能夠一鍵部署;系統需要變更時,僅需修改相關編排文件,即可完成改變。

對上文提到的幾個 Prometheus 不足之處,我們進行了如下設計:

  1. 引入 ELK 實現日誌監控,Logstash 負責採集日誌,日誌數據被保存到 Elasticsearch 裡,用戶則可以通過 Kibana 查詢到具體應用的日誌;

  2. 基於 OpenTracing 實現分佈式追蹤,最終完成了應用拓撲關係展示,調用鏈查詢等功能;

  3. 對 Netflix Turbine 進行了二次開發,將微服務框架的秒級監控納入到系統能力集裡。

輕舟微服務監控系統的實現細節

從架構上來講,輕舟微服務監控系統在設計時考慮到有多種用戶場景,併為此設計了多種模式,包括精簡模式、讀寫優化模式及多環境模式。

基於Prometheus的微服務監控實踐

圖 1 精簡模式架構

圖 1 描述了精簡模式的架構,精簡模式的主要特點在於部署簡單,容易維護。從整體上來看,我們使用了 Prometheus 經典的聯邦集群部署方案,處於葉子節點的 Prometheus 分片採集處理監控數據;處於根節點的 Prometheus 則直接從各個葉子節點上拉取處理後的監控數據並負責處理外部的查詢請求;告警服務則定期從位於根節點的 Prometheus 裡查詢監控數據,在發現數據達到閾值時發送告警通知至對應聯繫人。這個模式基本上解決了微服務監控的數據分片處理、多維度及系統可靠性問題,同時 ELK 系統及輕舟 APM 服務在日誌監控和分佈式追蹤方面進行功能補充,在規模不大的時候是能夠滿足用戶需求的。

基於Prometheus的微服務監控實踐

圖 2 讀寫優化模式架構

在精簡模式下,所有的維度監控數據都保存在本地磁盤裡面,當本地磁盤發生問題時,數據會有丟失的風險;同時精簡模式的可靠性主要靠多個 Prometheus 實例執行相同的監控任務來保證,多個實例之間實際上是沒有數據同步的,這使得數據有不一致的風險。為了解決上述問題,我們在讀寫優化模式里加入了網易自研的分佈式時序數據庫 NTSDB,利用 Prometheus 的 Remote Write/Read 機制將監控數據存取操作實際交由 NTSDB 來處理。由於 NTSDB 自帶數據同步機制,所以採用這種模式的數據安全性要高於第一種。

基於Prometheus的微服務監控實踐

圖 3 多環境模式架構

對於規模較大的用戶而言,還會存在多個物理隔離的機房。這些機房之間通常僅能夠通過網絡專線通信。針對這種情況,我們設計了多環境模式,在這個模式裡,每個環境的監控數據都保存在對應環境的 NTSDB 集群裡,僅當需要進行數據查詢時才會跨環境通信。這個模式在前兩個模式之外,解決了微服務監控的多數據中心及多 AZ 問題。

維度監控是輕舟微服務監控系統的主要部分,其實現細節如下所述:

基礎設施監控:就輕舟微服務平臺的具體情況來看,主要指的是容器監控。輕舟微服務的容器編排系統是 Kubernetes,Prometheus 則原生支持 Kubernetes 服務發現機制,這使得我們解決了監控對象發現問題;同時 Kubernetes 各組件原生支持 Prometheus,開源社區也提供了 Node exporter、kube-state-metrics exporter 及 Ceph Exporter,這些組件已經能夠滿足全部功能需求,所以在基礎設施監控上,系統完全採用了開源方案。

基於Prometheus的微服務監控實踐

圖 4 微服務框架監控具體架構

微服務框架監控:圖 4 顯示了這一維度監控的實現。在這一維度裡,我們自研了兩個組件,nsf-agent 和 nsf-turbine。nsf-agent 主要負責從服務實例裡收集並上報原始監控數據;nsf-turbine 則主要負責接收 nsf-agnet 推送的監控數據,同時對原始監控數據進行聚合及通過暴露這些監控數據給 Prometheus;Prometheus 定期拉取 nsf-turbine 暴露的監控數據併為這些數據提供持久化及數據查詢能力。另外,nsf-turbine 也提供了相對簡單的監控數據查詢接口,用戶能夠通過這個接口查詢到當日的實時統計數據及秒級監控數據。

應用監控:從總的結構上來講,應用監控分為客戶端、Collector 及 WEB 服務端部分;其中客戶端收集並上報應用的監控數據,這部分支持使用網易雲自研的 APM 客戶端或者開源的 Zipkin 及 Jaeger 客戶端,自研的 APM 客戶端能夠以無代碼侵入的方式進行數據採集,採集到的數據是滿足 OpenTracing 規範的,各個客戶端採集的監控數據將被上報到 Collector 裡進行處理,處理後的數據將被保存到 MySQL、ElasticSearch 或 Redis 裡;WEB 服務端部分則負責提供標準接口給 Prometheus 拉取數據。

當然,在基於 Prometheus 實現輕舟微服務監控系統的過程裡,我們也踩了一些坑,如:

  1. Prometheus 的各種計算函數都會對結果進行一定預估處理,其返回值通常都不是精確值。例如當聚合規則為獲取過去一小時的監控值之和,但實際只收集到十五分鐘監控數據時,這時候聚合出來的數據就是預估的值。如果需求非常精確的結果,需要通過客戶端來聚合計算。

  2. Prometheus 不支持定時整點進行聚合計算,只能計算過去一段時間的值 ; 無法獲取到諸如當天零點到次日零點這種規則的聚合數據。如有類似於這種的需求,需要通過客戶端直接聚合。

  3. Prometheus 預定義的計算規則、查詢表達式是非常多的,而且會根據具體需求進行變動,如果不採用版本管理工具來維護,是非常容易出錯的。

新的起點 - 我們的進展以及未來

目前輕舟微服務監控系統已經具備了下面的特性:

  • 高可用:在精簡模式裡,同一份監控數據至少由兩個 Prometheus 實例來採集;在讀寫優化和多環境模式裡,監控數據保存在分佈式時序數據庫 NTSDB 裡;任意一個 Prometheus 失效都不會影響到系統的整體功能。

  • 全局立體化:系統已經集成了基礎設施、微服務及應用等三個維度的監控告警;在日誌監控和分佈式追蹤等方面也提供了相應的日誌及調用鏈查詢審計功能;這些已經基本上涵蓋了微服務監控的全部功能需求。

  • 可動態調整:在前文提到的各種部署模式裡,我們對監控數據的採集和處理進行了分片。目前系統支持通過調整數據分片配置及 Prometheus 實例數,來滿足各種規模的微服務系統的監控需求。

另外,在不遠的將來,我們還會在下面幾個方面持續改進輕舟微服務監控系統:

  1. 系統自監控、智能監控及分佈式追蹤能力強化;

  2. 結合 Thanos、Druid 等組件,擴充部署模式及增強聚合能力;

  3. 增強監控及告警響應速度。

通過這些優化,輕舟微服務監控系統能夠更好地為企業的微服務系統保駕護航。


分享到:


相關文章: