網易雲基於 Prometheus 的微服務監控實踐
在過去數年裡,微服務的落地一直都是業界重點關注的問題。與傳統監控相比,微服務監控面臨著更多難點。這篇文章詳細介紹了網易雲輕舟微服務平臺是如何做監控的。
當監控遇上微服務
在過去數年裡,微服務的落地一直都是業界重點關注的問題,其始終面臨著部署、監控、配置和治理等方面的挑戰。輕舟微服務平臺是網易云為企業提供的一套微服務解決方案,其中微服務監控是其關注的重點問題之一。與傳統監控相比,微服務監控面臨著更多難點,包括:
-
監控物件動態可變,無法進行預先配置;
-
監控範圍非常繁雜,各類監控難以互相融合;
-
微服務例項間的呼叫關係非常複雜,故障排查會很困難;
-
微服務架構仍在快速發展,難以抽象出穩定的通用監控模型。
在工程角度也面臨著不少考驗,如:
-
在微服務架構裡,軟體系統通常會被拆分為數十甚至數百個微服務,這種拆分會使得監控資料爆炸增長,監控系統必須具備處理和展示這些資料的能力;
-
監控系統必須要保證可靠性,具體而言:保證不會因為單點故障而全域性失效,監控資料有備份機制,系統各服務的例項均可通過備份資料得到恢復;
-
監控系統必須支援雲上部署及快速水平擴容,這既是雲原生的基本要求,也符合企業系統微服務化演進的實際情況。
微服務監控的技術選型
微服務監控的諸多挑戰使得我們不得不慎重地進行技術選型。選擇開源還是再造輪子,這個問題在專案初期一直困擾著我們,經過一段時間的調研和論證,開源專案 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 雖然在上述六方面擁有優勢,但其仍然難以滿足微服務監控的所有需求,具體而言:
-
僅適用於維度監控,不能用於日誌監控、分散式追蹤等範圍;
-
告警規則和告警聯絡人僅支援通過靜態檔案配置;
-
原生支援的資料聚合函式有限且不支援擴充套件;
這些不足都說明了一個事實,Prometheus 社群版並非微服務監控的最終答案。
我們的答案 - 輕舟微服務監控系統
從大的方面來看,我們將微服務監控劃分為維度監控、日誌監控、分散式追蹤等三部分。其中維度監控在整個微服務監控裡最為重要,所佔比例也最大,此類監控的層級有如下劃分:
-
基礎設施監控: 主要對各個微服務例項所在的基礎設施進行監控,具體包括這些設施的執行狀態、資源使用情況及系統日誌進行監控,一般而言微服務應用例項會執行在容器裡,因此這個維度的監控物件也通常包含有容器編排系統、持續構建系統、映象倉庫等,這些物件的具體監控指標的範圍包括物件的健康狀態、執行狀態、資源使用情況等;
-
微服務通用監控:主要針對微服務通用指標進行監控,包括服務例項處理請求的情況及例項呼叫其它服務的情況,具體而言包括請求總數、請求處理時延(中位數,包括有 90、95 和 99 值)、請求結果(成功、失敗、熔斷、限流、超時和拒絕)統計、呼叫其它服務的結果(成功、失敗、熔斷、限流、超時和拒絕)統計及時延(中位數,包括有 90、95 和 99 值);
-
應用監控:主要對具體的微服務例項進行效能監控,通過資料自動化收集、資料視覺化展示,使使用者能夠及時、全面地掌控各個例項的效能情況,定位效能瓶頸。這一維度重點在於提供豐富的應用效能展示及效能問題定位功能,包括應用響應時間、吞吐量和狀態的展示,慢響應和錯誤明細的查詢。
-
通用中介軟體:我們沒有預置這個維度的監控到系統裡,不過得益於 Prometheus 完善的生態,系統保留有對常用資料庫、訊息佇列及快取進行監控的能力,具體包括 SQL/">MySQL、Redis、Memcached、Consul、RabbitMQ 及 Kafka 等。
在工程實現方面,我們進行了如下設計:
-
用 Prometheus 原生的聯邦叢集部署模式,使得全部監控資料分片處理;分片處理機制使得只需要增加例項個數就能夠應對海量監控資料問題;
-
多 Prometheus 例項作用於同一監控物件,使得單一例項失效也不會影響到此物件的監控,滿足高可用的要求;
-
監控系統所有元件及配置均實現容器化並由 Kubernetes 編排;理論上,在任意 Kubernetes 叢集裡都能夠一鍵部署;系統需要變更時,僅需修改相關編排檔案,即可完成改變。
對上文提到的幾個 Prometheus 不足之處,我們進行了如下設計:
-
引入 ELK 實現日誌監控,Logstash 負責採集日誌,日誌資料被儲存到 Elasticsearch 裡,使用者則可以通過 Kibana 查詢到具體應用的日誌;
-
基於 OpenTracing 實現分散式追蹤,最終完成了應用拓撲關係展示,呼叫鏈查詢等功能;
-
對 Netflix Turbine 進行了二次開發,將微服務框架的秒級監控納入到系統能力集裡。
輕舟微服務監控系統的實現細節
從架構上來講,輕舟微服務監控系統在設計時考慮到有多種使用者場景,併為此設計了多種模式,包括精簡模式、讀寫優化模式及多環境模式。

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

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

圖 3 多環境模式架構
對於規模較大的使用者而言,還會存在多個物理隔離的機房。這些機房之間通常僅能夠通過網路專線通訊。針對這種情況,我們設計了多環境模式,在這個模式裡,每個環境的監控資料都儲存在對應環境的 NTSDB 叢集裡,僅當需要進行資料查詢時才會跨環境通訊。這個模式在前兩個模式之外,解決了微服務監控的多資料中心及多 AZ 問題。
維度監控是輕舟微服務監控系統的主要部分,其實現細節如下所述:
基礎設施監控:就輕舟微服務平臺的具體情況來看,主要指的是容器監控。輕舟微服務的容器編排系統是 Kubernetes,Prometheus 則原生支援 Kubernetes 服務發現機制,這使得我們解決了監控物件發現問題;同時 Kubernetes 各元件原生支援 Prometheus,開源社群也提供了 Node exporter、kube-state-metrics exporter 及 Ceph Exporter,這些元件已經能夠滿足全部功能需求,所以在基礎設施監控上,系統完全採用了開源方案。

圖 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 實現輕舟微服務監控系統的過程裡,我們也踩了一些坑,如:
-
Prometheus 的各種計算函式都會對結果進行一定預估處理,其返回值通常都不是精確值。例如當聚合規則為獲取過去一小時的監控值之和,但實際只收集到十五分鐘監控資料時,這時候聚合出來的資料就是預估的值。如果需求非常精確的結果,需要通過客戶端來聚合計算。
-
Prometheus 不支援定時整點進行聚合計算,只能計算過去一段時間的值 ; 無法獲取到諸如當天零點到次日零點這種規則的聚合資料。如有類似於這種的需求,需要通過客戶端直接聚合。
-
Prometheus 預定義的計算規則、查詢表示式是非常多的,而且會根據具體需求進行變動,如果不採用版本管理工具來維護,是非常容易出錯的。
新的起點 - 我們的進展以及未來
目前輕舟微服務監控系統已經具備了下面的特性:
-
高可用:在精簡模式裡,同一份監控資料至少由兩個 Prometheus 例項來採集;在讀寫優化和多環境模式裡,監控資料儲存在分散式時序資料庫 NTSDB 裡;任意一個 Prometheus 失效都不會影響到系統的整體功能。
-
全域性立體化:系統已經集成了基礎設施、微服務及應用等三個維度的監控告警;在日誌監控和分散式追蹤等方面也提供了相應的日誌及呼叫鏈查詢審計功能;這些已經基本上涵蓋了微服務監控的全部功能需求。
-
可動態調整:在前文提到的各種部署模式裡,我們對監控資料的採集和處理進行了分片。目前系統支援通過調整資料分片配置及 Prometheus 例項數,來滿足各種規模的微服務系統的監控需求。
另外,在不遠的將來,我們還會在下面幾個方面持續改進輕舟微服務監控系統:
-
系統自監控、智慧監控及分散式追蹤能力強化;
-
結合 Thanos、Druid 等元件,擴充部署模式及增強聚合能力;
-
增強監控及告警響應速度。
通過這些優化,輕舟微服務監控系統能夠更好地為企業的微服務系統保駕護航。
作者簡介
王添,網易雲高階服務端開發工程師,畢業於華中科技大學。畢業後一直就職於網易杭州研究院雲端計算技術部,主要負責網易雲輕舟微服務、容器服務等研發工作,目前對微服務監控、智慧告警及分散式健康檢查等方向非常感興趣。
陳諮餘,網易雲資深平臺開發工程師,畢業於浙江大學。目前就職於網易杭州研究院雲端計算技術部,主要負責網易雲輕舟應用效能監控以及管理、日誌服務等研發工作。
活動推薦
百度服務可用性工程建設?美團外賣業務異常檢測系統建設與實踐?阿里智慧化故障治理流程探索和實踐?12 月 7-8 日,ArchSummit 全球架構師峰會將在北京國際會議中心隆重舉行,行業大咖現身說法,分享智慧高效運維的案例和實踐!
點選“閱讀原文”,火熱訂票中…票務 MM 聯絡方式:17326843116(微信同號)