网易云基于Prometheus的微服务监控实践
當(dāng)監(jiān)控遇上微服務(wù)
在過去數(shù)年里,微服務(wù)的落地一直都是業(yè)界重點(diǎn)關(guān)注的問題,其始終面臨著部署、監(jiān)控、配置和治理等方面的挑戰(zhàn)。輕舟微服務(wù)平臺(tái)是網(wǎng)易云為企業(yè)提供的一套微服務(wù)解決方案,其中微服務(wù)監(jiān)控是其關(guān)注的重點(diǎn)問題之一。與傳統(tǒng)監(jiān)控相比,微服務(wù)監(jiān)控面臨著更多難點(diǎn),包括:
監(jiān)控對象動(dòng)態(tài)可變,無法進(jìn)行預(yù)先配置;
監(jiān)控范圍非常繁雜,各類監(jiān)控難以互相融合;
微服務(wù)實(shí)例間的調(diào)用關(guān)系非常復(fù)雜,故障排查會(huì)很困難;
微服務(wù)架構(gòu)仍在快速發(fā)展,難以抽象出穩(wěn)定的通用監(jiān)控模型。
在工程角度也面臨著不少考驗(yàn),如:
在微服務(wù)架構(gòu)里,軟件系統(tǒng)通常會(huì)被拆分為數(shù)十甚至數(shù)百個(gè)微服務(wù),這種拆分會(huì)使得監(jiān)控?cái)?shù)據(jù)爆炸增長,監(jiān)控系統(tǒng)必須具備處理和展示這些數(shù)據(jù)的能力;
監(jiān)控系統(tǒng)必須要保證可靠性,具體而言:保證不會(huì)因?yàn)閱吸c(diǎn)故障而全局失效,監(jiān)控?cái)?shù)據(jù)有備份機(jī)制,系統(tǒng)各服務(wù)的實(shí)例均可通過備份數(shù)據(jù)得到恢復(fù);
監(jiān)控系統(tǒng)必須支持云上部署及快速水平擴(kuò)容,這既是云原生的基本要求,也符合企業(yè)系統(tǒng)微服務(wù)化演進(jìn)的實(shí)際情況。
微服務(wù)監(jiān)控的技術(shù)選型
微服務(wù)監(jiān)控的諸多挑戰(zhàn)使得我們不得不慎重地進(jìn)行技術(shù)選型。選擇開源還是再造輪子,這個(gè)問題在項(xiàng)目初期一直困擾著我們,經(jīng)過一段時(shí)間的調(diào)研和論證,開源項(xiàng)目Prometheus成了最終的答案。
Prometheus是CNCF旗下的項(xiàng)目,該項(xiàng)目是一個(gè)用于系統(tǒng)和應(yīng)用服務(wù)監(jiān)控的軟件,它能夠以給定的時(shí)間間隔從給定目標(biāo)中收集監(jiān)控指標(biāo),并能夠通過特定查詢表達(dá)式獲取查詢結(jié)果。
選擇Prometheus的主要原因是:
靈活的數(shù)據(jù)模型:在Prometheus里,監(jiān)控?cái)?shù)據(jù)是由值、時(shí)間戳和標(biāo)簽表組成的,其中監(jiān)控?cái)?shù)據(jù)的源信息是完全記錄在標(biāo)簽表里的;同時(shí)Prometheus支持在監(jiān)控?cái)?shù)據(jù)采集階段對監(jiān)控?cái)?shù)據(jù)的標(biāo)簽表進(jìn)行修改,這使其具備強(qiáng)大的擴(kuò)展能力;
強(qiáng)大的查詢能力:Prometheus提供有數(shù)據(jù)查詢語言PromQL。從表現(xiàn)上來看,PromQL提供了大量的數(shù)據(jù)計(jì)算函數(shù),大部分情況下用戶都可以直接通過PromQL從Prometheus里查詢到需要的聚合數(shù)據(jù);
健全的生態(tài): Prometheus能夠直接對常見操作系統(tǒng)、中間件、數(shù)據(jù)庫、硬件及編程語言進(jìn)行監(jiān)控;同時(shí)社區(qū)提供有Java/Golang/Ruby語言客戶端SDK,用戶能夠快速實(shí)現(xiàn)自定義監(jiān)控項(xiàng)及監(jiān)控邏輯;
良好的性能:在性能方面來看,Prometheus提供了PromBench基準(zhǔn)測試,從最新測試結(jié)果來看,在硬件資源滿足的情況下,Prometheus單實(shí)例在每秒采集10w條監(jiān)控?cái)?shù)據(jù)的情況下,在數(shù)據(jù)處理和查詢方面依然有著不錯(cuò)的性能表現(xiàn);
更契合的架構(gòu):采用推模型的監(jiān)控系統(tǒng),客戶端需要負(fù)責(zé)在服務(wù)端上進(jìn)行注冊及監(jiān)控?cái)?shù)據(jù)推送;而在Prometheus采用的拉模型架構(gòu)里,具體的數(shù)據(jù)拉取行為是完全由服務(wù)端來決定的。服務(wù)端是可以基于某種服務(wù)發(fā)現(xiàn)機(jī)制來自動(dòng)發(fā)現(xiàn)監(jiān)控對象,多個(gè)服務(wù)端之間能夠通過集群機(jī)制來實(shí)現(xiàn)數(shù)據(jù)分片。推模型想要實(shí)現(xiàn)相同的功能,通常需要客戶端進(jìn)行配合,這在微服務(wù)架構(gòu)里是比較困難的;
成熟的社區(qū):Prometheus是CNCF組織第二個(gè)畢業(yè)的開源項(xiàng)目,擁有活躍的社區(qū);成立至今,社區(qū)已經(jīng)發(fā)布了一百多個(gè)P版本,項(xiàng)目在GitHub上獲得的star數(shù)超過了2萬。
Prometheus雖然在上述六方面擁有優(yōu)勢,但其仍然難以滿足微服務(wù)監(jiān)控的所有需求,具體而言:
僅適用于維度監(jiān)控,不能用于日志監(jiān)控、分布式追蹤等范圍;
告警規(guī)則和告警聯(lián)系人僅支持通過靜態(tài)文件配置;
原生支持的數(shù)據(jù)聚合函數(shù)有限且不支持?jǐn)U展;
這些不足都說明了一個(gè)事實(shí),Prometheus社區(qū)版并非微服務(wù)監(jiān)控的最終答案。
我們的答案-輕舟微服務(wù)監(jiān)控系統(tǒng)的設(shè)計(jì)
從大的方面來看,我們將微服務(wù)監(jiān)控劃分為維度監(jiān)控、日志監(jiān)控、分布式追蹤等三部分。其中維度監(jiān)控在整個(gè)微服務(wù)監(jiān)控里最為重要,所占比例也最大,此類監(jiān)控的層級有如下劃分:
基礎(chǔ)設(shè)施監(jiān)控:主要對各個(gè)微服務(wù)實(shí)例所在的基礎(chǔ)設(shè)施進(jìn)行監(jiān)控,具體包括這些設(shè)施的運(yùn)行狀態(tài)、資源使用情況及系統(tǒng)日志進(jìn)行監(jiān)控,一般而言微服務(wù)應(yīng)用實(shí)例會(huì)運(yùn)行在容器里,因此這個(gè)維度的監(jiān)控對象也通常包含有容器編排系統(tǒng)、持續(xù)構(gòu)建系統(tǒng)、鏡像倉庫等,這些對象的具體監(jiān)控指標(biāo)的范圍包括對象的健康狀態(tài)、運(yùn)行狀態(tài)、資源使用情況等;
微服務(wù)通用監(jiān)控:主要針對微服務(wù)通用指標(biāo)進(jìn)行監(jiān)控,包括服務(wù)實(shí)例處理請求的情況及實(shí)例調(diào)用其它服務(wù)的情況,具體而言包括請求總數(shù)、請求處理時(shí)延(中位數(shù),包括有90、95和99值)、請求結(jié)果(成功、失敗、熔斷、限流、超時(shí)和拒絕)統(tǒng)計(jì)、調(diào)用其它服務(wù)的結(jié)果(成功、失敗、熔斷、限流、超時(shí)和拒絕)統(tǒng)計(jì)及時(shí)延(中位數(shù),包括有90、95和99值);
應(yīng)用監(jiān)控:主要對具體的微服務(wù)實(shí)例進(jìn)行性能監(jiān)控,通過數(shù)據(jù)自動(dòng)化收集、數(shù)據(jù)可視化展示,使用戶能夠及時(shí)、全面地掌控各個(gè)實(shí)例的性能情況,定位性能瓶頸。這一維度重點(diǎn)在于提供豐富的應(yīng)用性能展示及性能問題定位功能,包括應(yīng)用響應(yīng)時(shí)間、吞吐量和狀態(tài)的展示,慢響應(yīng)和錯(cuò)誤明細(xì)的查詢。
通用中間件:我們沒有預(yù)置這個(gè)維度的監(jiān)控到系統(tǒng)里,不過得益于Prometheus完善的生態(tài),系統(tǒng)保留有對常用數(shù)據(jù)庫、消息隊(duì)列及緩存進(jìn)行監(jiān)控的能力,具體包括MySQL、Redis、Memcached、Consul、RabbitMQ及Kafka等。
在工程實(shí)現(xiàn)方面,我們進(jìn)行了如下設(shè)計(jì):
用Prometheus原生的聯(lián)邦集群部署模式,使得全部監(jiān)控?cái)?shù)據(jù)分片處理;分片處理機(jī)制使得只需要增加實(shí)例個(gè)數(shù)就能夠應(yīng)對海量監(jiān)控?cái)?shù)據(jù)問題;
多Prometheus實(shí)例作用于同一監(jiān)控對象,使得單一實(shí)例失效也不會(huì)影響到此對象的監(jiān)控,滿足高可用的要求;
監(jiān)控系統(tǒng)所有組件及配置均實(shí)現(xiàn)容器化并由Kubernetes編排;理論上,在任意Kubernetes集群里都能夠一鍵部署;系統(tǒng)需要變更時(shí),僅需修改相關(guān)編排文件,即可完成改變。
對上文提到的幾個(gè)Prometheus不足之處,我們進(jìn)行了如下設(shè)計(jì):
引入ELK實(shí)現(xiàn)日志監(jiān)控,Logstash負(fù)責(zé)采集日志,日志數(shù)據(jù)被保存到Elasticsearch里,用戶則可以通過Kibana查詢到具體應(yīng)用的日志;
基于OpenTracing實(shí)現(xiàn)分布式追蹤,最終完成了應(yīng)用拓?fù)潢P(guān)系展示,調(diào)用鏈查詢等功能;
對Netflix Turbine進(jìn)行了二次開發(fā),將微服務(wù)框架的秒級監(jiān)控納入到系統(tǒng)能力集里。
多場景多維度-輕舟監(jiān)控系統(tǒng)的實(shí)現(xiàn)細(xì)節(jié)
從架構(gòu)上來講,輕舟微服務(wù)監(jiān)控系統(tǒng)在設(shè)計(jì)時(shí)考慮到有多種用戶場景,并為此設(shè)計(jì)了多種模式,包括精簡模式、讀寫優(yōu)化模式及多環(huán)境模式。
圖1描述了精簡模式的架構(gòu),精簡模式的主要特點(diǎn)在于部署簡單,容易維護(hù)。從整體上來看,我們使用了Prometheus經(jīng)典的聯(lián)邦集群部署方案,處于葉子節(jié)點(diǎn)的Prometheus分片采集處理監(jiān)控?cái)?shù)據(jù);處于根節(jié)點(diǎn)的Prometheus則直接從各個(gè)葉子節(jié)點(diǎn)上拉取處理后的監(jiān)控?cái)?shù)據(jù)并負(fù)責(zé)處理外部的查詢請求;告警服務(wù)則定期從位于根節(jié)點(diǎn)的Prometheus里查詢監(jiān)控?cái)?shù)據(jù),在發(fā)現(xiàn)數(shù)據(jù)達(dá)到閾值時(shí)發(fā)送告警通知至對應(yīng)聯(lián)系人。這個(gè)模式基本上解決了微服務(wù)監(jiān)控的數(shù)據(jù)分片處理、多維度及系統(tǒng)可靠性問題,同時(shí)ELK系統(tǒng)及輕舟APM服務(wù)在日志監(jiān)控和分布式追蹤方面進(jìn)行功能補(bǔ)充,在規(guī)模不大的時(shí)候是能夠滿足用戶需求的。
在精簡模式下,所有的維度監(jiān)控?cái)?shù)據(jù)都保存在本地磁盤里面,當(dāng)本地磁盤發(fā)生問題時(shí),數(shù)據(jù)會(huì)有丟失的風(fēng)險(xiǎn);同時(shí)精簡模式的可靠性主要靠多個(gè)Prometheus實(shí)例執(zhí)行相同的監(jiān)控任務(wù)來保證,多個(gè)實(shí)例之間實(shí)際上是沒有數(shù)據(jù)同步的,這使得數(shù)據(jù)有不一致的風(fēng)險(xiǎn)。為了解決上述問題,我們在讀寫優(yōu)化模式里加入了網(wǎng)易自研的分布式時(shí)序數(shù)據(jù)庫NTSDB,利用Prometheus的Remote Write/Read機(jī)制將監(jiān)控?cái)?shù)據(jù)存取操作實(shí)際交由NTSDB來處理。由于NTSDB自帶數(shù)據(jù)同步機(jī)制,所以采用這種模式的數(shù)據(jù)安全性要高于第一種。
對于規(guī)模較大的用戶而言,還會(huì)存在多個(gè)物理隔離的機(jī)房。這些機(jī)房之間通常僅能夠通過網(wǎng)絡(luò)專線通信。針對這種情況,我們設(shè)計(jì)了多環(huán)境模式,在這個(gè)模式里,每個(gè)環(huán)境的監(jiān)控?cái)?shù)據(jù)都保存在對應(yīng)環(huán)境的NTSDB集群里,僅當(dāng)需要進(jìn)行數(shù)據(jù)查詢時(shí)才會(huì)跨環(huán)境通信。這個(gè)模式在前兩個(gè)模式之外,解決了微服務(wù)監(jiān)控的多數(shù)據(jù)中心及多AZ問題。
維度監(jiān)控是輕舟微服務(wù)監(jiān)控系統(tǒng)的主要部分,其實(shí)現(xiàn)細(xì)節(jié)如下所述:
- 基礎(chǔ)設(shè)施監(jiān)控:就輕舟微服務(wù)平臺(tái)的具體情況來看,主要指的是容器監(jiān)控。輕舟微服務(wù)的容器編排系統(tǒng)是Kubernetes,Prometheus則原生支持Kubernetes服務(wù)發(fā)現(xiàn)機(jī)制,這使得我們解決了監(jiān)控對象發(fā)現(xiàn)問題;同時(shí)Kubernetes各組件原生支持Prometheus,開源社區(qū)也提供了Node exporter、kube-state-metrics exporter及Ceph Exporter,這些組件已經(jīng)能夠滿足全部功能需求,所以在基礎(chǔ)設(shè)施監(jiān)控上,系統(tǒng)完全采用了開源方案。
微服務(wù)框架監(jiān)控:圖4顯示了這一維度監(jiān)控的實(shí)現(xiàn)。在這一維度里,我們自研了兩個(gè)組件,nsf-agent和nsf-turbine。nsf-agent主要負(fù)責(zé)從服務(wù)實(shí)例里收集并上報(bào)原始監(jiān)控?cái)?shù)據(jù);nsf-turbine則主要負(fù)責(zé)接收nsf-agnet推送的監(jiān)控?cái)?shù)據(jù),同時(shí)對原始監(jiān)控?cái)?shù)據(jù)進(jìn)行聚合及通過暴露這些監(jiān)控?cái)?shù)據(jù)給Prometheus;Prometheus定期拉取nsf-turbine暴露的監(jiān)控?cái)?shù)據(jù)并為這些數(shù)據(jù)提供持久化及數(shù)據(jù)查詢能力。另外,nsf-turbine也提供了相對簡單的監(jiān)控?cái)?shù)據(jù)查詢接口,用戶能夠通過這個(gè)接口查詢到當(dāng)日的實(shí)時(shí)統(tǒng)計(jì)數(shù)據(jù)及秒級監(jiān)控?cái)?shù)據(jù)。
應(yīng)用監(jiān)控:從總的結(jié)構(gòu)上來講,應(yīng)用監(jiān)控分為客戶端、Collector及WEB服務(wù)端部分;其中客戶端收集并上報(bào)應(yīng)用的監(jiān)控?cái)?shù)據(jù),這部分支持使用網(wǎng)易云自研的APM客戶端或者開源的Zipkin及Jaeger客戶端,自研的APM客戶端能夠以無代碼侵入的方式進(jìn)行數(shù)據(jù)采集,采集到的數(shù)據(jù)是滿足OpenTracing規(guī)范的,各個(gè)客戶端采集的監(jiān)控?cái)?shù)據(jù)將被上報(bào)到Collector里進(jìn)行處理,處理后的數(shù)據(jù)將被保存到MySQL、ElasticSearch或Redis里;WEB服務(wù)端部分則負(fù)責(zé)提供標(biāo)準(zhǔn)接口給Prometheus拉取數(shù)據(jù)。
當(dāng)然,在基于Prometheus實(shí)現(xiàn)輕舟微服務(wù)監(jiān)控系統(tǒng)的過程里,我們也踩了一些坑,如:
Prometheus的各種計(jì)算函數(shù)都會(huì)對結(jié)果進(jìn)行一定預(yù)估處理,其返回值通常都不是精確值。例如當(dāng)聚合規(guī)則為獲取過去一小時(shí)的監(jiān)控值之和,但實(shí)際只收集到十五分鐘監(jiān)控?cái)?shù)據(jù)時(shí),這時(shí)候聚合出來的數(shù)據(jù)就是預(yù)估的值。如果需求非常精確的結(jié)果,需要通過客戶端來聚合計(jì)算。
Prometheus不支持定時(shí)整點(diǎn)進(jìn)行聚合計(jì)算,只能計(jì)算過去一段時(shí)間的值;無法獲取到諸如當(dāng)天零點(diǎn)到次日零點(diǎn)這種規(guī)則的聚合數(shù)據(jù)。如有類似于這種的需求,需要通過客戶端直接聚合。
Prometheus預(yù)定義的計(jì)算規(guī)則、查詢表達(dá)式是非常多的,而且會(huì)根據(jù)具體需求進(jìn)行變動(dòng),如果不采用版本管理工具來維護(hù),是非常容易出錯(cuò)的。
新的起點(diǎn)-我們的進(jìn)展以及未來
目前輕舟微服務(wù)監(jiān)控系統(tǒng)已經(jīng)具備了下面的特性:
高可用:在精簡模式里,同一份監(jiān)控?cái)?shù)據(jù)至少由兩個(gè)Prometheus實(shí)例來采集;在讀寫優(yōu)化和多環(huán)境模式里,監(jiān)控?cái)?shù)據(jù)保存在分布式時(shí)序數(shù)據(jù)庫NTSDB里;任意一個(gè)Prometheus失效都不會(huì)影響到系統(tǒng)的整體功能。
全局立體化:系統(tǒng)已經(jīng)集成了基礎(chǔ)設(shè)施、微服務(wù)及應(yīng)用等三個(gè)維度的監(jiān)控告警;在日志監(jiān)控和分布式追蹤等方面也提供了相應(yīng)的日志及調(diào)用鏈查詢審計(jì)功能;這些已經(jīng)基本上涵蓋了微服務(wù)監(jiān)控的全部功能需求。
可動(dòng)態(tài)調(diào)整:在前文提到的各種部署模式里,我們對監(jiān)控?cái)?shù)據(jù)的采集和處理進(jìn)行了分片。目前系統(tǒng)支持通過調(diào)整數(shù)據(jù)分片配置及Prometheus實(shí)例數(shù),來滿足各種規(guī)模的微服務(wù)系統(tǒng)的監(jiān)控需求。
另外,在不遠(yuǎn)的將來,我們還會(huì)在下面幾個(gè)方面持續(xù)改進(jìn)輕舟微服務(wù)監(jiān)控系統(tǒng):
系統(tǒng)自監(jiān)控、智能監(jiān)控及分布式追蹤能力強(qiáng)化;
結(jié)合Thanos、Druid等組件,擴(kuò)充部署模式及增強(qiáng)聚合能力;
增強(qiáng)監(jiān)控及告警響應(yīng)速度。
通過這些優(yōu)化,輕舟微服務(wù)監(jiān)控系統(tǒng)能夠更好地為企業(yè)的微服務(wù)系統(tǒng)保駕護(hù)航。
作者簡介
王添,網(wǎng)易云高級服務(wù)端開發(fā)工程師,畢業(yè)于華中科技大學(xué)。畢業(yè)后一直就職于網(wǎng)易杭州研究院云計(jì)算技術(shù)部,主要負(fù)責(zé)網(wǎng)易云輕舟微服務(wù)、容器服務(wù)等研發(fā)工作,目前對微服務(wù)監(jiān)控、智能告警及分布式健康檢查等方向非常感興趣。
陳咨余,網(wǎng)易云資深平臺(tái)開發(fā)工程師,畢業(yè)于浙江大學(xué)。目前就職于網(wǎng)易杭州研究院云計(jì)算技術(shù)部,主要負(fù)責(zé)網(wǎng)易云輕舟應(yīng)用性能監(jiān)控以及管理、日志服務(wù)等研發(fā)工作。
相關(guān)推薦
12 月 7 日北京 ArchSummit 全球架構(gòu)師峰會(huì)上,來自網(wǎng)易嚴(yán)選的技術(shù)專家邱似峰,將分享“數(shù)據(jù)驅(qū)動(dòng)下的嚴(yán)選倉儲(chǔ)供應(yīng)鏈智能優(yōu)化”內(nèi)容,重點(diǎn)介紹“工程+大數(shù)據(jù)+人工智能算法”的應(yīng)用。詳情點(diǎn)擊 https://bj2018.archsummit.com/schedule
總結(jié)
以上是生活随笔為你收集整理的网易云基于Prometheus的微服务监控实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL-常用引擎
- 下一篇: 使用DiskFileItemFactor