网易云基于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完善的生態,系統保留有對常用數據庫、消息隊列及緩存進行監控的能力,具體包括MySQL、Redis、Memcached、Consul、RabbitMQ及Kafka等。
在工程實現方面,我們進行了如下設計:
用Prometheus原生的聯邦集群部署模式,使得全部監控數據分片處理;分片處理機制使得只需要增加實例個數就能夠應對海量監控數據問題;
多Prometheus實例作用于同一監控對象,使得單一實例失效也不會影響到此對象的監控,滿足高可用的要求;
監控系統所有組件及配置均實現容器化并由Kubernetes編排;理論上,在任意Kubernetes集群里都能夠一鍵部署;系統需要變更時,僅需修改相關編排文件,即可完成改變。
對上文提到的幾個Prometheus不足之處,我們進行了如下設計:
引入ELK實現日志監控,Logstash負責采集日志,日志數據被保存到Elasticsearch里,用戶則可以通過Kibana查詢到具體應用的日志;
基于OpenTracing實現分布式追蹤,最終完成了應用拓撲關系展示,調用鏈查詢等功能;
對Netflix Turbine進行了二次開發,將微服務框架的秒級監控納入到系統能力集里。
多場景多維度-輕舟監控系統的實現細節
從架構上來講,輕舟微服務監控系統在設計時考慮到有多種用戶場景,并為此設計了多種模式,包括精簡模式、讀寫優化模式及多環境模式。
圖1描述了精簡模式的架構,精簡模式的主要特點在于部署簡單,容易維護。從整體上來看,我們使用了Prometheus經典的聯邦集群部署方案,處于葉子節點的Prometheus分片采集處理監控數據;處于根節點的Prometheus則直接從各個葉子節點上拉取處理后的監控數據并負責處理外部的查詢請求;告警服務則定期從位于根節點的Prometheus里查詢監控數據,在發現數據達到閾值時發送告警通知至對應聯系人。這個模式基本上解決了微服務監控的數據分片處理、多維度及系統可靠性問題,同時ELK系統及輕舟APM服務在日志監控和分布式追蹤方面進行功能補充,在規模不大的時候是能夠滿足用戶需求的。
在精簡模式下,所有的維度監控數據都保存在本地磁盤里面,當本地磁盤發生問題時,數據會有丟失的風險;同時精簡模式的可靠性主要靠多個Prometheus實例執行相同的監控任務來保證,多個實例之間實際上是沒有數據同步的,這使得數據有不一致的風險。為了解決上述問題,我們在讀寫優化模式里加入了網易自研的分布式時序數據庫NTSDB,利用Prometheus的Remote Write/Read機制將監控數據存取操作實際交由NTSDB來處理。由于NTSDB自帶數據同步機制,所以采用這種模式的數據安全性要高于第一種。
對于規模較大的用戶而言,還會存在多個物理隔離的機房。這些機房之間通常僅能夠通過網絡專線通信。針對這種情況,我們設計了多環境模式,在這個模式里,每個環境的監控數據都保存在對應環境的NTSDB集群里,僅當需要進行數據查詢時才會跨環境通信。這個模式在前兩個模式之外,解決了微服務監控的多數據中心及多AZ問題。
維度監控是輕舟微服務監控系統的主要部分,其實現細節如下所述:
- 基礎設施監控:就輕舟微服務平臺的具體情況來看,主要指的是容器監控。輕舟微服務的容器編排系統是Kubernetes,Prometheus則原生支持Kubernetes服務發現機制,這使得我們解決了監控對象發現問題;同時Kubernetes各組件原生支持Prometheus,開源社區也提供了Node exporter、kube-state-metrics exporter及Ceph Exporter,這些組件已經能夠滿足全部功能需求,所以在基礎設施監控上,系統完全采用了開源方案。
微服務框架監控:圖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 日北京 ArchSummit 全球架構師峰會上,來自網易嚴選的技術專家邱似峰,將分享“數據驅動下的嚴選倉儲供應鏈智能優化”內容,重點介紹“工程+大數據+人工智能算法”的應用。詳情點擊 https://bj2018.archsummit.com/schedule
總結
以上是生活随笔為你收集整理的网易云基于Prometheus的微服务监控实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL-常用引擎
- 下一篇: 使用DiskFileItemFactor