淺談微服務(wù)的發(fā)展以及可觀測(cè)性
作者 | 陳亦帥,中國(guó)移動(dòng)云能力中心PaaS產(chǎn)品部
近年來(lái),“云原生”頻繁出現(xiàn)在人們的視野中。隨著云原生成為下一代云計(jì)算的技術(shù)“內(nèi)核”,業(yè)界正在從關(guān)注“云原生概念”轉(zhuǎn)變到關(guān)注“云原生落地實(shí)踐”。云原生技術(shù)發(fā)展勢(shì)不可擋,依然會(huì)是未來(lái)云計(jì)算領(lǐng)域的熱門(mén)話題。
我們知道,現(xiàn)代”云原生”是一套符合云計(jì)算發(fā)展趨勢(shì)的應(yīng)用設(shè)計(jì)理念方法論,其關(guān)鍵技術(shù)中包含了微服務(wù)架構(gòu)、容器、容器化編排、服務(wù)網(wǎng)格等技術(shù)。那么當(dāng)我們把大型系統(tǒng)拆解成一個(gè)個(gè)獨(dú)立部署的模塊,進(jìn)行容器化部署,得益于此團(tuán)隊(duì)可以更加快速、持續(xù)、規(guī)??斓倪M(jìn)行開(kāi)發(fā)和交付系統(tǒng)。但事物都有兩面性,我們從方案或者技術(shù)“好”的一面中“獲利”的同時(shí),必須同時(shí)規(guī)避解決“壞”的一面帶來(lái)的風(fēng)險(xiǎn)和后果,其中比較大一項(xiàng)就是微服務(wù)化后系統(tǒng)復(fù)雜性的成倍上升而帶來(lái)運(yùn)維和問(wèn)題排查難度陡增的巨大挑戰(zhàn)。
01微服務(wù)架構(gòu)演進(jìn)歷史
在真正進(jìn)入微服務(wù)可觀測(cè)性這個(gè)話題之前,我們有必要了解下微服務(wù)架構(gòu)的演進(jìn)歷史。從整體上看,整體架構(gòu)的演變過(guò)程大致經(jīng)歷了單體應(yīng)用架構(gòu)、垂直應(yīng)用架構(gòu)、分布式SOA架構(gòu)、微服務(wù)架構(gòu)的演變。我們以一個(gè)電商系統(tǒng)舉例(以下圖片均來(lái)自網(wǎng)上),主要比較下各個(gè)架構(gòu)之間在運(yùn)維方面的區(qū)別。
舉例的電商系統(tǒng)大致分為三個(gè)主體模塊:主體業(yè)務(wù)模塊(用戶管理、商品管理、訂單管理)、內(nèi)容管理模塊(CMS管理)、系統(tǒng)管理模塊(后臺(tái)管理)。
單體應(yīng)用架構(gòu)
如圖所示,單體應(yīng)用架構(gòu)把所有模塊都揉進(jìn)了一個(gè)應(yīng)用內(nèi),所有模塊均耦合在一起。系統(tǒng)的健康狀況通常“所見(jiàn)即所得”(整體功能可用便表示應(yīng)用處于健康狀態(tài)),監(jiān)測(cè)和告警指標(biāo)通常由JVM的一些參數(shù)進(jìn)行反饋,應(yīng)用日志產(chǎn)生和收集比較統(tǒng)一集中,排查問(wèn)題的鏈路通常比較短(大多問(wèn)題可由日志直接定位到應(yīng)用內(nèi)的某行代碼進(jìn)而分析原因),維護(hù)和監(jiān)控起來(lái)難度不大。但通常一個(gè)子模塊的問(wèn)題會(huì)導(dǎo)致整體項(xiàng)目出現(xiàn)不可用,無(wú)法水平擴(kuò)展,過(guò)于臃腫無(wú)法適配大型項(xiàng)目和應(yīng)用。之后便逐漸演變?yōu)榇怪睉?yīng)用架構(gòu)。
垂直應(yīng)用架構(gòu)
相比較于單體應(yīng)用架構(gòu),我們對(duì)整體系統(tǒng)進(jìn)行了拆分,優(yōu)點(diǎn)是可以根據(jù)實(shí)際情況對(duì)某個(gè)子系統(tǒng)進(jìn)行水平擴(kuò)展,一個(gè)系統(tǒng)發(fā)生故障可以避免對(duì)其他系統(tǒng)產(chǎn)生影響。缺點(diǎn)是拆分后系統(tǒng)比較獨(dú)立無(wú)法相互調(diào)用(不同于微服務(wù),只是獨(dú)立拆分)也導(dǎo)致了重復(fù)業(yè)務(wù)的開(kāi)發(fā),如圖中箭頭所示的訂單管理、商品管理、用戶管理部分,后期維護(hù)成本較高。運(yùn)維方面,難度提升的地方主要在于日志的管理和問(wèn)題發(fā)生點(diǎn)的增加,例如一個(gè)問(wèn)題的發(fā)生可能同時(shí)由CMS和后臺(tái)管理系統(tǒng)導(dǎo)致,需要同時(shí)解決兩個(gè)系統(tǒng)的故障。但業(yè)務(wù)規(guī)模的擴(kuò)大,會(huì)導(dǎo)致重復(fù)代碼和重復(fù)修復(fù)工作的激增,我們需要將該部分的邏輯進(jìn)行抽取,繼而慢慢過(guò)渡到分布式SOA架構(gòu)。
分布式SOA架構(gòu)
分布式SOA架構(gòu)也可認(rèn)為是微服務(wù)架構(gòu)的雛形,其中展示層對(duì)應(yīng)我們通常所說(shuō)的消費(fèi)者或者Controller層,負(fù)責(zé)控制頁(yè)面操作需要調(diào)用服務(wù)層的哪些服務(wù)(例如:下單操作使用到用戶、訂單、商品三個(gè)服務(wù),而這三個(gè)服務(wù)又是抽象在服務(wù)層獨(dú)立存在的),而服務(wù)層是具體的業(yè)務(wù)邏輯實(shí)現(xiàn)供表現(xiàn)層調(diào)用,上圖的服務(wù)層模塊應(yīng)該包括用戶管理、商品管理、訂單管理、CMS管理、后臺(tái)管理等所有模塊,并且基于SOA的分布式通常還會(huì)包含一個(gè)注冊(cè)中心(例如:圖中的ESB總線或者類似DUBBO這樣的框架)。
作為微服務(wù)架構(gòu)的雛形,在解決了水平擴(kuò)展問(wèn)題的同時(shí),注冊(cè)中心的加入既解決了服務(wù)之間的注冊(cè)發(fā)現(xiàn)和調(diào)用,也使公共模塊和邏輯服務(wù)得到了抽取獨(dú)立。但同時(shí)也開(kāi)始讓運(yùn)維監(jiān)測(cè)壓力有了比較大的增加,性能和告警關(guān)注的服務(wù)變多,同時(shí)還需要關(guān)注注冊(cè)中心的健康,日志分布更加散亂,業(yè)務(wù)發(fā)生故障時(shí),排查鏈路變得冗長(zhǎng),對(duì)于復(fù)雜業(yè)務(wù)問(wèn)題我們通常需要同時(shí)獲取從展示層、注冊(cè)中心到服務(wù)層的日志,并分析其關(guān)系才能比較好的定位出問(wèn)題,這無(wú)論對(duì)運(yùn)維還是應(yīng)用性能提升都是一個(gè)挑戰(zhàn)。并且服務(wù)之間的依賴與調(diào)用關(guān)系復(fù)雜,服務(wù)提供方與調(diào)用方接口耦合,業(yè)務(wù)切分不夠細(xì)的問(wèn)題也讓微服務(wù)架構(gòu)登上舞臺(tái)。
微服務(wù)架構(gòu)
現(xiàn)在我們所屬的微服務(wù)架構(gòu)通常由一個(gè)網(wǎng)關(guān)以及各個(gè)功能獨(dú)立的微小服務(wù)構(gòu)成,服務(wù)之間的可以相互調(diào)用,它們的可用性可由容器和容器編排的能力提供。服務(wù)劃分的更細(xì)、職責(zé)更加明確,服務(wù)之間可使用RPC、REST進(jìn)行相互調(diào)用,同時(shí)為前端提供HTTP接口。
由于服務(wù)的徹底拆分,服務(wù)的開(kāi)發(fā)可以分發(fā)給各個(gè)小團(tuán)隊(duì)進(jìn)行獨(dú)立開(kāi)發(fā)、部署和升級(jí)。并且每個(gè)微服務(wù)可以根據(jù)業(yè)務(wù)實(shí)際運(yùn)行情況進(jìn)行水平擴(kuò)容,但同時(shí)微服務(wù)過(guò)多,服務(wù)治理成本變得更高,同時(shí)還要考慮分布式事務(wù)、容錯(cuò)等技術(shù)。從運(yùn)維方面看,服務(wù)日志變得更加分散,怎么對(duì)全局的微服務(wù)進(jìn)行監(jiān)控和告警難度更大了,最后出現(xiàn)業(yè)務(wù)問(wèn)題進(jìn)行排查時(shí),鏈路變得非常冗長(zhǎng),若沒(méi)有一個(gè)全局追蹤id,只通過(guò)日志的時(shí)間戳,無(wú)論是業(yè)務(wù)性能優(yōu)化還是故障排除都會(huì)變得十分困難。即業(yè)界不斷在討論研究的問(wèn)題,微服務(wù)的可觀測(cè)性。
02什么是微服務(wù)的可觀測(cè)性
從上一節(jié)的架構(gòu)的演變過(guò)程中,我們可以看出隨著服務(wù)越拆越細(xì),越拆越獨(dú)立,運(yùn)維的難度以及系統(tǒng)的復(fù)雜度都成倍的提升,我們不得不面對(duì)以下幾個(gè)問(wèn)題:
- 隨著模塊之間的調(diào)用關(guān)系由進(jìn)程內(nèi)函數(shù)的調(diào)用變?yōu)檫M(jìn)程間通過(guò)網(wǎng)絡(luò)的調(diào)用,如何檢測(cè)和保證網(wǎng)絡(luò)的可靠。
- 調(diào)用鏈路的時(shí)間越來(lái)越長(zhǎng),流量的走向變得越發(fā)不可控,如何高效的排查問(wèn)題或者提升應(yīng)用的性能。
- 現(xiàn)代微服務(wù)的實(shí)踐和部署往往結(jié)合Kubernetes、Docker、Service Mesh等云原生技術(shù),開(kāi)發(fā)團(tuán)隊(duì)更加難感知其下的基礎(chǔ)設(shè)施的狀態(tài)了。
傳統(tǒng)對(duì)于系統(tǒng)的監(jiān)控,我們往往關(guān)注諸如CPU、內(nèi)存、網(wǎng)絡(luò)、應(yīng)用接口的請(qǐng)求量、接口的響應(yīng)量等,但這對(duì)于微服務(wù)系統(tǒng)來(lái)說(shuō),并不能幫助我們掌握整體系統(tǒng)的運(yùn)行情況。這就像一條輪胎、一個(gè)水箱、一箱油,這些事物分開(kāi)獨(dú)立放置時(shí)我們能夠比較簡(jiǎn)單的判定其狀態(tài),但當(dāng)這些東西被組合進(jìn)一個(gè)“系統(tǒng)”,例如一輛汽車后,如何在汽車運(yùn)行過(guò)程中,觀測(cè)到其狀態(tài),就變成了影響汽車穩(wěn)定性的重要一環(huán),這對(duì)微服務(wù)系統(tǒng)來(lái)說(shuō)同樣適用。
微服務(wù)的可觀測(cè)性即是要解決數(shù)據(jù)流在客戶端輸入后,透明的知曉其在各個(gè)服務(wù)間進(jìn)行采集、傳輸、存儲(chǔ)的狀態(tài),進(jìn)而解決預(yù)測(cè)系統(tǒng)運(yùn)行過(guò)程中出現(xiàn)故障的問(wèn)題。
為了保證這些數(shù)據(jù)流的狀態(tài)被感知,業(yè)界普遍認(rèn)為有幾類數(shù)據(jù)可作為可觀測(cè)性的支柱:Metrics、Logging、Tracing。
其中Metrics是在一段時(shí)間內(nèi)組成單個(gè)邏輯測(cè)量、計(jì)數(shù)器或直方圖的原子,例如,服務(wù)調(diào)用的QPS、響應(yīng)時(shí)間、錯(cuò)誤請(qǐng)求發(fā)生率,目的是為了創(chuàng)建集中式度量系統(tǒng),側(cè)重于技術(shù)指標(biāo)的收集與觀測(cè);Logging用于記錄離散的事件,例如,應(yīng)用程序的調(diào)試信息或錯(cuò)誤信息,目的是搭建集中式日志系統(tǒng),側(cè)重于統(tǒng)一采集、存儲(chǔ)與檢索各個(gè)微服務(wù)的日志;Tracing處理請(qǐng)求范圍內(nèi)的信息,例如,一次遠(yuǎn)程方法調(diào)用的執(zhí)行過(guò)程和耗時(shí),目的是形成分布式追蹤系統(tǒng),側(cè)重于串聯(lián)請(qǐng)求在微服務(wù)間的調(diào)用情況、繼而進(jìn)行追蹤與APM分析。
通過(guò)以上信息,我們可以對(duì)已有的系統(tǒng)進(jìn)行分類。例如,ZipKin、Jaeger專注于Tracing領(lǐng)域,Prometheus專注于Metrics領(lǐng)域,ELK、Loki專注于Logging領(lǐng)域。但是各個(gè)系統(tǒng)也都在不斷的集成其他領(lǐng)域的特性到自身系統(tǒng)中來(lái),例如,Jaeger遵循的一些OpenTracing規(guī)范,但CNCF已經(jīng)開(kāi)始把OpenTracing和OpenCensus合并成 OpenTelemetry 項(xiàng)目,以后的會(huì)有更多即包含了一定Tracing能力同時(shí)又有Metrics的系統(tǒng)出現(xiàn),Prometheus雖然一開(kāi)始專注于指標(biāo)的收集和管理,但也在開(kāi)始集成一些Tracing的能力。
現(xiàn)在業(yè)界對(duì)于微服務(wù)可觀測(cè)性的一種解決方案既是,首先使用loki + Grafana進(jìn)行分布日志的統(tǒng)一收集與管理,使用Prometheus和Grafana對(duì) Metrics 進(jìn)行存儲(chǔ)和展示,最后再使用諸如類似Jaeger的追蹤系統(tǒng)做分布式追蹤的存儲(chǔ)和展示。基于此,我們可以大致獲得如下的一個(gè)問(wèn)題分析鏈路:
首先,我們通過(guò)Email或者某種方式收到一個(gè)告警信息,接著去Grafana的圖表中看查看某一段時(shí)間的指標(biāo)異常情況,再下鉆就可以在Prometheus中查看到某一個(gè)異常指標(biāo)的詳細(xì)情況,就可以獲得對(duì)應(yīng)某個(gè)異常發(fā)生的時(shí)間或節(jié)點(diǎn),根據(jù)時(shí)間和節(jié)點(diǎn)以及服務(wù)標(biāo)簽從Loki中撈取日志信息中的request
id或者一個(gè)全局的trace id,然后再根據(jù)這個(gè)trace id去類似Jaeger這種滿足OpenTelemetry
規(guī)范的系統(tǒng)中查找調(diào)用鏈,獲得某個(gè)服務(wù)的異?;蛘咝阅茼憫?yīng)詳情,最終排除出問(wèn)題記錄issue。這是一個(gè)比較常規(guī)的微服務(wù)問(wèn)題排查方法,雖然一定程度上解決了可觀測(cè)性的問(wèn)題,但是仍然比較冗長(zhǎng)。業(yè)界也已經(jīng)出現(xiàn)了類似exemplar這樣的組件,能夠串聯(lián)各個(gè)割裂的組件,或者各個(gè)廠商也在嘗試推出類似Erda
Cloud這樣的一站式解決方法,使上文提到的Logging、Tracing、Metrics不斷的向中心圓靠攏。
03總結(jié)
微服務(wù)架構(gòu)和云原生的發(fā)展使我們能夠更加從容的面對(duì)大數(shù)據(jù)時(shí)代大型系統(tǒng)的開(kāi)發(fā),同時(shí)系統(tǒng)運(yùn)維排查過(guò)程中問(wèn)題鏈路追蹤、應(yīng)用日志的管理、故障的監(jiān)控告警等也變得越發(fā)復(fù)雜,業(yè)界起初出現(xiàn)了針對(duì)各個(gè)問(wèn)題的對(duì)應(yīng)的獨(dú)立解決方案,但慢慢也趨于集中提供能夠串聯(lián)和一站式的平臺(tái)系統(tǒng)。微服務(wù)的可觀測(cè)性問(wèn)題一直都是困擾著整體應(yīng)用穩(wěn)定性的一環(huán),在之后的文章中,我們也期待與大家分享更多相關(guān)技術(shù)細(xì)節(jié)和實(shí)戰(zhàn)文章。