国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于負(fù)載關(guān)系圖的微服務(wù)自動(dòng)伸縮方法

2022-07-12 14:03趙文耘
關(guān)鍵詞:調(diào)用實(shí)例監(jiān)控

冀 超 彭 鑫 趙文耘

(復(fù)旦大學(xué)軟件學(xué)院 上海 201203) (上海市數(shù)據(jù)科學(xué)重點(diǎn)實(shí)驗(yàn)室 上海 201203)

0 引 言

微服務(wù)(Microservice)架構(gòu)是一種目前在企業(yè)實(shí)踐中得到廣泛應(yīng)用的軟件架構(gòu)。微服務(wù)架構(gòu)將一整個(gè)軟件應(yīng)用按照細(xì)粒度的模塊劃分規(guī)則解耦成一個(gè)個(gè)功能獨(dú)立的模塊[1]。每個(gè)模塊獨(dú)立開發(fā)與部署,擁有獨(dú)立的進(jìn)程與運(yùn)行環(huán)境。各個(gè)模塊通過RPC或HTTP等輕量級(jí)的通信協(xié)議調(diào)用其他模塊的接口,協(xié)同完成系統(tǒng)功能。這樣的模塊稱之為微服務(wù)。目前微服務(wù)架構(gòu)已成為云原生技術(shù)[2]領(lǐng)域的關(guān)鍵技術(shù)[3],并在企業(yè)中得到廣泛使用[4]。例如,Netflix公司用了7年時(shí)間完成了由單體系統(tǒng)向微服務(wù)系統(tǒng)的遷移工作[5];騰訊公司的微信系統(tǒng)包含了部署在20 000多臺(tái)虛擬機(jī)上的3 000多個(gè)微服務(wù)[6]。

微服務(wù)細(xì)粒度功能劃分與獨(dú)立運(yùn)行環(huán)境的特性使得軟件系統(tǒng)的部署更具靈活性與動(dòng)態(tài)性。一個(gè)微服務(wù)一般部署若干個(gè)副本共同分流請(qǐng)求,稱為微服務(wù)實(shí)例。當(dāng)系統(tǒng)某些部分的負(fù)載產(chǎn)生變化時(shí),系統(tǒng)將會(huì)調(diào)整這些功能涉及微服務(wù)實(shí)例的數(shù)量。例如,在用餐高峰時(shí)間,外賣訂餐系統(tǒng)增加負(fù)責(zé)點(diǎn)單的微服務(wù)實(shí)例以應(yīng)對(duì)增長的請(qǐng)求;而在夜間和凌晨時(shí)段,一些微服務(wù)部署副本將會(huì)被刪除以節(jié)約運(yùn)算資源。開發(fā)人員希望微服務(wù)實(shí)例可以自動(dòng)伸縮,自動(dòng)地適應(yīng)系統(tǒng)不斷變化的負(fù)載。但是,微服務(wù)之間存在復(fù)雜的網(wǎng)狀調(diào)用負(fù)載關(guān)系。如果獨(dú)立地對(duì)各個(gè)微服務(wù)的伸縮需求進(jìn)行計(jì)量,很容易導(dǎo)致負(fù)載瓶頸從一個(gè)微服務(wù)沿著網(wǎng)狀關(guān)系傳遞到另一個(gè)微服務(wù)上,使得系統(tǒng)在多輪伸縮操作后才達(dá)到穩(wěn)態(tài),導(dǎo)致自動(dòng)伸縮操作所耗時(shí)間較長。

為了解決上述問題,本文提出基于負(fù)載關(guān)系圖的微服務(wù)自動(dòng)伸縮方法。首先,本文對(duì)微服務(wù)負(fù)載關(guān)系圖進(jìn)行了定義,并介紹了其構(gòu)建與更新過程及數(shù)據(jù)抽取方法。接著,本文介紹了基于負(fù)載關(guān)系圖的自動(dòng)伸縮方法。該方法在自動(dòng)伸縮操作觸發(fā)后,根據(jù)微服務(wù)負(fù)載關(guān)系圖評(píng)估各個(gè)微服務(wù)的新時(shí)段預(yù)期負(fù)載強(qiáng)度,并計(jì)算各個(gè)微服務(wù)的伸縮需求,最后一并完成所有微服務(wù)的伸縮操作?;谇笆龇椒ǎ疚脑O(shè)計(jì)并實(shí)現(xiàn)一個(gè)面向部署在Kubernetes平臺(tái)上的微服務(wù)系統(tǒng)的自動(dòng)伸縮工具LRGAS。最后,本文使用TrainTicket開源微服務(wù)基準(zhǔn)系統(tǒng)開展了自動(dòng)伸縮方法的對(duì)比實(shí)驗(yàn),并通過實(shí)驗(yàn)驗(yàn)證了本文方法的高效性。

1 相關(guān)工作

微服務(wù)架構(gòu)功能劃分的細(xì)粒度性與運(yùn)行環(huán)境的隔離使得各個(gè)微服務(wù)的部署具有很高的靈活性與動(dòng)態(tài)性。當(dāng)系統(tǒng)負(fù)載增加時(shí),系統(tǒng)可以為特定的微服務(wù)分配更多資源以提高其請(qǐng)求處理能力。系統(tǒng)可以為現(xiàn)有的微服務(wù)實(shí)例分配更多的CPU使用時(shí)間、內(nèi)存空間以提高單個(gè)實(shí)例的請(qǐng)求處理能力,這種方式稱為縱向伸縮;系統(tǒng)也可以保持單個(gè)微服務(wù)實(shí)例的資源限額不變,但增加微服務(wù)實(shí)例的數(shù)量以分流請(qǐng)求,這樣的方式稱為橫向伸縮。橫向伸縮相比縱向伸縮具有更高的靈活性與可操作性,因此目前微服務(wù)的自動(dòng)伸縮大多使用橫向伸縮的方式。該方法的工作方式為:開發(fā)人員在部署微服務(wù)時(shí)設(shè)定某個(gè)監(jiān)控指標(biāo)的上下門限值;當(dāng)負(fù)載變化使得監(jiān)控指標(biāo)超出門限值范圍時(shí),微服務(wù)系統(tǒng)自動(dòng)增加或減少實(shí)例數(shù)量,確保指標(biāo)在門限值范圍內(nèi)。該方法常被用到作為門限值的監(jiān)控指標(biāo)有CPU使用時(shí)間、內(nèi)存占用量或是請(qǐng)求響應(yīng)時(shí)間等。目前使用最為廣泛的Kubernetes容器編排平臺(tái)的橫向伸縮方法便是使用該方法。

由于目前的自動(dòng)伸縮方法在微服務(wù)指標(biāo)超出門限值范圍后才觸發(fā)伸縮操作,導(dǎo)致伸縮操作存在滯后性。一些研究嘗試對(duì)微服務(wù)實(shí)例監(jiān)控指標(biāo)的未來走勢(shì)進(jìn)行預(yù)測(cè)[7-10],進(jìn)而在系統(tǒng)流量變化前預(yù)先完成伸縮操作。其中,文獻(xiàn)[7]提出了一套基于微服務(wù)工作負(fù)載預(yù)測(cè)的自動(dòng)伸縮框架。該框架借助人工神經(jīng)網(wǎng)絡(luò)、遞歸神經(jīng)網(wǎng)絡(luò)及資源擴(kuò)展優(yōu)化算法構(gòu)建了一個(gè)自動(dòng)化系統(tǒng),借助微服務(wù)系統(tǒng)的基礎(chǔ)架構(gòu)層數(shù)據(jù)完成各個(gè)服務(wù)的自動(dòng)伸縮操作。此外,由于指標(biāo)的選取和門限值的設(shè)定依賴于開發(fā)人員的經(jīng)驗(yàn),這導(dǎo)致門限值的設(shè)定并不準(zhǔn)確。一些研究[11-12]致力于尋找可以更精準(zhǔn)反映微服務(wù)伸縮需求的指標(biāo)。文獻(xiàn)[11]在自動(dòng)伸縮所使用的監(jiān)控指標(biāo)類型上進(jìn)行了改進(jìn)。該方法構(gòu)建了工具M(jìn)icroscaler,通過對(duì)接口的響應(yīng)時(shí)間進(jìn)行統(tǒng)計(jì)和計(jì)算定義了微服務(wù)的“服務(wù)能力”指標(biāo)。該指標(biāo)對(duì)微服務(wù)負(fù)載強(qiáng)度的描述比其他監(jiān)控指標(biāo)更為準(zhǔn)確,計(jì)算伸縮需求時(shí)也更加精確。目前的工具和研究大多關(guān)注微服務(wù)監(jiān)控指標(biāo)門限值的預(yù)測(cè)、設(shè)定和監(jiān)控指標(biāo)的選取和定義。這些研究存在的問題是,微服務(wù)之間存在著復(fù)雜的調(diào)用關(guān)系,但目前的伸縮方法獨(dú)立地考慮各個(gè)微服務(wù)的伸縮需求,無法避免負(fù)載瓶頸轉(zhuǎn)移的問題發(fā)生。自動(dòng)伸縮方法應(yīng)當(dāng)統(tǒng)籌規(guī)劃整個(gè)系統(tǒng)中各個(gè)微服務(wù)伸縮操作,一次性并行對(duì)多個(gè)相關(guān)微服務(wù)并容,使得系統(tǒng)可以盡快達(dá)到穩(wěn)態(tài)以滿足新的負(fù)載需求。

2 背景知識(shí)

2.1 容器、容器編排與服務(wù)網(wǎng)格

微服務(wù)架構(gòu)的引入使得軟件應(yīng)用的部署方式產(chǎn)生了變化。一個(gè)微服務(wù)系統(tǒng)包含許多獨(dú)立部署的微服務(wù)實(shí)例,它們的部署配置環(huán)境可能互相產(chǎn)生沖突,這使得運(yùn)行環(huán)境管理變得復(fù)雜。容器技術(shù)的出現(xiàn)解決了這個(gè)問題。容器技術(shù)借助操作系統(tǒng)提供的命名空間和資源隔離機(jī)制,將一臺(tái)虛擬機(jī)上同時(shí)運(yùn)行的多個(gè)微服務(wù)實(shí)例的運(yùn)行環(huán)境隔離,避免了進(jìn)程間運(yùn)行環(huán)境沖突的問題。容器平臺(tái)還提供了統(tǒng)一的部署與運(yùn)行接口,抹平了不同虛擬機(jī)之間的差異性,使得各個(gè)微服務(wù)可以無差異地在各種機(jī)器環(huán)境下分發(fā)與部署。目前最為廣泛使用的容器技術(shù)是Docker[13]。

容器技術(shù)解決了微服務(wù)獨(dú)立部署和運(yùn)行的問題,但是沒有解決微服務(wù)集群的維護(hù)與管理的問題。在微服務(wù)系統(tǒng)的部署過程中,部署平臺(tái)需要把各個(gè)微服務(wù)實(shí)例調(diào)度到空閑資源充足的虛擬機(jī)上去;同時(shí)為了避免各個(gè)微服務(wù)實(shí)例網(wǎng)絡(luò)地址沖突問題,需要從全局對(duì)各個(gè)微服務(wù)實(shí)例的地址進(jìn)行唯一性分配;此外,為了保證系統(tǒng)的正常運(yùn)行,系統(tǒng)需要確保有預(yù)期數(shù)量的微服務(wù)實(shí)例處于正常運(yùn)行狀態(tài)。為了解決這樣的需求,容器編排平臺(tái)出現(xiàn)。借助容器編排平臺(tái),開發(fā)人員可以自定義微服務(wù)系統(tǒng)的部署方案,簡化微服務(wù)系統(tǒng)的部署與維護(hù)工作。目前在實(shí)際生產(chǎn)實(shí)踐中廣泛使用的平臺(tái)有Kubernetes[14]、Docker Swarm[15]、Mesos[16]、Spring Cloud[17]等,這些平臺(tái)都對(duì)微服務(wù)系統(tǒng)所需要的功能進(jìn)行了不同程度的實(shí)現(xiàn)。目前最為廣泛使用的容器編排平臺(tái)是Kubernetes,已成為容器編排平臺(tái)的事實(shí)標(biāo)準(zhǔn)。目前也有一些關(guān)于微服務(wù)編排工具的研究[18-19]實(shí)現(xiàn)了前述功能。例如,文獻(xiàn)[18]提出了一套名為MiCADO的微服務(wù)編排工具,提供了云應(yīng)用的自動(dòng)伸縮功能。

隨著微服務(wù)系統(tǒng)規(guī)模的擴(kuò)大,微服務(wù)之間的交互關(guān)系也變得越來越復(fù)雜,這使得系統(tǒng)內(nèi)部的網(wǎng)絡(luò)配置與操控變得困難。例如,在新服務(wù)上線時(shí)開發(fā)人員希望流量按照比例逐漸切換到新的服務(wù)上;而有些時(shí)候,開發(fā)人員希望根據(jù)請(qǐng)求的元信息分流某些請(qǐng)求。在這種情況下,需要一個(gè)全局的控制平面來對(duì)系統(tǒng)內(nèi)部網(wǎng)絡(luò)流量進(jìn)行管理,而服務(wù)網(wǎng)格技術(shù)解決了這個(gè)問題。服務(wù)網(wǎng)格向每一個(gè)運(yùn)行的微服務(wù)實(shí)例中添加一個(gè)邊車組件(sidecar)用于接管微服務(wù)實(shí)例的所有網(wǎng)絡(luò)操作,使得微服務(wù)系統(tǒng)內(nèi)部的網(wǎng)絡(luò)交互實(shí)際上變成sidecar之間的網(wǎng)絡(luò)交互。如此一來,開發(fā)人員即可通過配置規(guī)則并將其應(yīng)用于sidecar的方式來對(duì)整個(gè)應(yīng)用內(nèi)部的網(wǎng)絡(luò)調(diào)用進(jìn)行操控。Istio[20]是服務(wù)網(wǎng)格技術(shù)的典型代表。

2.2 微服務(wù)系統(tǒng)的調(diào)用鏈追蹤

微服務(wù)系統(tǒng)內(nèi)部存在著復(fù)雜的調(diào)用關(guān)系,一個(gè)請(qǐng)求的處理過程往往需要一到多個(gè)微服務(wù)的協(xié)同。在系統(tǒng)的運(yùn)行過程中,為了在故障發(fā)生時(shí)對(duì)請(qǐng)求的調(diào)用關(guān)系進(jìn)行追蹤以便查明故障,需要對(duì)微服務(wù)系統(tǒng)的調(diào)用鏈進(jìn)行追蹤,以便獲取請(qǐng)求被各個(gè)微服務(wù)實(shí)例處理的順序和處理時(shí)間等數(shù)據(jù)。

OpenTracing標(biāo)準(zhǔn)[21]是目前被廣為接納的微服務(wù)鏈路追蹤標(biāo)準(zhǔn)。根據(jù)OpenTracing標(biāo)準(zhǔn)的數(shù)據(jù)模型定義,一個(gè)完整的請(qǐng)求鏈路與OpenTracing中的一條Trace所對(duì)應(yīng),而一個(gè)完整請(qǐng)求鏈路中的每次跨服務(wù)服務(wù)調(diào)用(如一次RPC或HTTP調(diào)用)則對(duì)應(yīng)OpenTracing的一條Span。也就是說,一條Trace是由若干個(gè)Span構(gòu)成的樹狀結(jié)構(gòu)或是有向無環(huán)圖。如圖1所示,用戶向微服務(wù)A發(fā)送一條請(qǐng)求,系統(tǒng)生成對(duì)應(yīng)的調(diào)用鏈Trace_x。該請(qǐng)求分別產(chǎn)生了對(duì)微服務(wù)B、微服務(wù)C、微服務(wù)D、微服務(wù)E的調(diào)用,并生成對(duì)應(yīng)的4條Span。OpenTracing還定義了Trace和Span中應(yīng)該包括的諸多指標(biāo)數(shù)據(jù)、標(biāo)簽等信息。通過這些信息,開發(fā)人員可以得到請(qǐng)求調(diào)用中的細(xì)節(jié)信息,例如請(qǐng)求的來源、目的地、發(fā)生時(shí)間、時(shí)延等。

圖1 Request、Trace與Span關(guān)系

OpenTracing標(biāo)準(zhǔn)目前有很多開源項(xiàng)目實(shí)現(xiàn)。Spring Cloud Sleuth是一個(gè)Java庫,將其引入基于Spring框架的Java微服務(wù)項(xiàng)目后,即可通過在跨服務(wù)調(diào)用的請(qǐng)求Header頭上插入特定請(qǐng)求ID的方式,將整條調(diào)用鏈串接起來。Zipkin是一個(gè)開源調(diào)用鏈?zhǔn)占驼故竟ぞ撸瑪?shù)據(jù)存儲(chǔ)和UI界面兩部分。Spring Cloud Sleuth會(huì)將自動(dòng)生成調(diào)用鏈傳輸給Zipkin進(jìn)行存儲(chǔ)。開發(fā)人員可以借助其UI界面完成調(diào)用鏈的查詢和展示。該調(diào)用鏈追蹤系統(tǒng)的架構(gòu)如圖2所示。

圖2 Zipkin調(diào)用鏈追蹤系統(tǒng)架構(gòu)

3 微服務(wù)負(fù)載關(guān)系圖

與單體應(yīng)用不同,微服務(wù)系統(tǒng)的各個(gè)微服務(wù)完成獨(dú)立的功能并使用獨(dú)立的方式部署,并通過調(diào)用其他微服務(wù)的方式協(xié)同完成一系列功能。這樣的情況使得不同微服務(wù)之間的依賴關(guān)系不同:有些微服務(wù)之間聯(lián)系緊密,而有些微服務(wù)之間很少發(fā)生調(diào)用關(guān)系。整個(gè)系統(tǒng)的自動(dòng)伸縮操作必須考慮到微服務(wù)間的負(fù)載關(guān)系的不同,并對(duì)各個(gè)微服務(wù)實(shí)行不同程度的伸縮操作。

為了達(dá)到前述目的,本文設(shè)計(jì)并定義微服務(wù)負(fù)載關(guān)系圖。該圖描述了過去時(shí)間內(nèi)系統(tǒng)中各個(gè)微服務(wù)之間的負(fù)載強(qiáng)度關(guān)系,其中:節(jié)點(diǎn)表示微服務(wù);兩個(gè)節(jié)點(diǎn)間關(guān)系表示兩個(gè)微服務(wù)發(fā)生過調(diào)用關(guān)系;關(guān)系上的數(shù)字是對(duì)一段時(shí)間內(nèi)調(diào)用次數(shù)的記錄,反映了兩個(gè)微服務(wù)之間一段時(shí)間內(nèi)的負(fù)載強(qiáng)度。每個(gè)微服務(wù)的負(fù)載強(qiáng)度等于所有指向其關(guān)系上的負(fù)載總和。如圖3是一個(gè)包含6個(gè)微服務(wù)的微服務(wù)負(fù)載關(guān)系圖的示例?!拔⒎?wù)系統(tǒng)外部”是一個(gè)特殊的節(jié)點(diǎn),代表使用微服務(wù)系統(tǒng)的用戶方。微服務(wù)A、F直接接收外部請(qǐng)求,并調(diào)用系統(tǒng)內(nèi)部的微服務(wù)B、C、D等。本文將微服務(wù)A、F這樣的系統(tǒng)外部請(qǐng)求首先到達(dá)的微服務(wù)稱為系統(tǒng)的入口微服務(wù)。入口微服務(wù)同時(shí)也是請(qǐng)求調(diào)用鏈中第一個(gè)出現(xiàn)的微服務(wù)。

圖3 微服務(wù)負(fù)載關(guān)系圖示例

微服務(wù)負(fù)載關(guān)系圖的數(shù)據(jù)來源于調(diào)用鏈監(jiān)控系統(tǒng)收集的調(diào)用鏈數(shù)據(jù)。正常運(yùn)行的微服務(wù)系統(tǒng)一段時(shí)間會(huì)采集到大量調(diào)用鏈日志,而每條調(diào)用鏈日志(即Trace)中包含若干次跨服務(wù)調(diào)用(即Span)。每條Span都可以提取出一個(gè)微服務(wù)對(duì)另一個(gè)微服務(wù)的一次調(diào)用。圖4為一條Span數(shù)據(jù)的示例。可以看出,這是一次ts-login-service對(duì)ts-sso-service的調(diào)用。

圖4 調(diào)用鏈日志示例

微服務(wù)負(fù)載關(guān)系圖隨著系統(tǒng)運(yùn)行持續(xù)進(jìn)行構(gòu)建與更新。該過程固定間隔時(shí)間循環(huán)執(zhí)行,主要包括以下步驟:1) 從調(diào)用鏈平臺(tái)中抽取最近一個(gè)時(shí)間段內(nèi)新產(chǎn)生的Trace數(shù)據(jù);2) 對(duì)于每條Trace,逐個(gè)檢查其包含的Span數(shù)據(jù),記錄調(diào)用發(fā)起方的微服務(wù)名稱和調(diào)用接收方的微服務(wù)名稱;3) 對(duì)記錄的兩個(gè)微服務(wù)間的每次調(diào)用,將負(fù)載關(guān)系圖中對(duì)應(yīng)關(guān)系上記錄的數(shù)字加一;4) 將新的負(fù)載關(guān)系數(shù)據(jù)存入數(shù)據(jù)庫中,取代舊數(shù)據(jù),等待一段時(shí)間后返回1)步繼續(xù)下一輪更新。經(jīng)過更新后的節(jié)點(diǎn)間關(guān)系上記錄的數(shù)字便是兩個(gè)微服務(wù)之間的負(fù)載強(qiáng)度。

4 自動(dòng)伸縮方法

4.1 問題分析與過程概述

目前廣泛使用的基于指標(biāo)門限值設(shè)定和監(jiān)控的微服務(wù)自動(dòng)伸縮方法存在一些不足。按照該方法,當(dāng)僅僅針對(duì)某一個(gè)繁忙的服務(wù)進(jìn)行伸縮時(shí),系統(tǒng)的負(fù)載瓶頸很有可能會(huì)很快轉(zhuǎn)移到另一個(gè)下游的微服務(wù),進(jìn)而引發(fā)另一次伸縮,如此迭代多次后才能最終達(dá)到相對(duì)穩(wěn)定狀態(tài)。這樣的方式將會(huì)使得系統(tǒng)較長時(shí)間處于正在伸縮狀態(tài),不利于系統(tǒng)迅速適應(yīng)新的負(fù)載需求。當(dāng)某些功能的訪問量變化時(shí),需要一并找到所有可能受到較大影響的微服務(wù)進(jìn)行伸縮,而不是孤立地對(duì)監(jiān)控指標(biāo)超標(biāo)的微服務(wù)逐個(gè)進(jìn)行伸縮。

圖3為包含6個(gè)微服務(wù)的調(diào)用負(fù)載示意圖??梢钥闯觯谝欢螘r(shí)間內(nèi),微服務(wù)A共接收了100次調(diào)用,并分別調(diào)用了80次微服務(wù)B和5次微服務(wù)C;微服務(wù)F接受了10次調(diào)用,并分別調(diào)用了10次微服務(wù)C和10次微服務(wù)D;微服務(wù)B和微服務(wù)D分別調(diào)用了微服務(wù)E共計(jì)130次和20次。根據(jù)數(shù)據(jù)看出,微服務(wù)A和微服務(wù)B、微服務(wù)E三者之間關(guān)系密切,而微服務(wù)A和微服務(wù)C之間關(guān)系并不緊密。這意味著,如果微服務(wù)A為了應(yīng)對(duì)劇增的用戶請(qǐng)求而進(jìn)行伸縮,那么微服務(wù)B首先會(huì)受到大量請(qǐng)求的沖擊而引發(fā)伸縮操作,進(jìn)而影響蔓延到微服務(wù)E,微服務(wù)C由于接收微服務(wù)A的負(fù)載較少,基本不會(huì)受到影響。假設(shè)微服務(wù)A伸縮所需時(shí)間為TA,微服務(wù)B的伸縮所需時(shí)間為TB,微服務(wù)E的伸縮所需時(shí)間為TE。如果使用傳統(tǒng)的微服務(wù)自動(dòng)伸縮方法,微服務(wù)系統(tǒng)最終完成所有伸縮操作所需總時(shí)間Told為:

Told=TA+TB+TE

(1)

如果可以在微服務(wù)伸縮操作前分析微服務(wù)間的調(diào)用關(guān)系,確定微服務(wù)的伸縮需求后再并行進(jìn)行伸縮,那么所需要的總時(shí)間Tnew為:

Tnew=max(TA,TB,TE)

(2)

根據(jù)上述分析可以看出,在各個(gè)微服務(wù)伸縮所需時(shí)間相近的情況下,改進(jìn)后的方法可以大大減少整個(gè)系統(tǒng)伸縮操作所需要的時(shí)間。其主要原理是,通過分析服務(wù)間負(fù)載關(guān)系的方法,將多個(gè)需要伸縮的微服務(wù)從串行伸縮變成并行伸縮。

本節(jié)提出的微服務(wù)自動(dòng)伸縮方法主要包括兩個(gè)部分:首先該方法從微服務(wù)歷史調(diào)用鏈日志中提取整個(gè)系統(tǒng)過去一個(gè)時(shí)段的微服務(wù)負(fù)載關(guān)系圖。接著,通過監(jiān)控系統(tǒng)獲取到的入口微服務(wù)的請(qǐng)求頻率變化幅度,借助微服務(wù)負(fù)載關(guān)系圖分析系統(tǒng)中各個(gè)微服務(wù)的負(fù)載水平,最終得出各個(gè)微服務(wù)的伸縮需求。

基于負(fù)載關(guān)系圖的微服務(wù)自動(dòng)伸縮方法的流程如圖5所示,共包含4個(gè)步驟:1) 觸發(fā)自動(dòng)伸縮。此步使用與傳統(tǒng)自動(dòng)伸縮相同的觸發(fā)方法,即設(shè)置監(jiān)控指標(biāo)的門限值并對(duì)其進(jìn)行監(jiān)控,在指標(biāo)越過門限值時(shí)觸發(fā)自動(dòng)伸縮。2) 計(jì)算各個(gè)微服務(wù)的預(yù)期負(fù)載。自動(dòng)伸縮觸發(fā)后,根據(jù)入口微服務(wù)請(qǐng)求頻率的變化,借助微服務(wù)間負(fù)載關(guān)系評(píng)估各個(gè)微服務(wù)在新時(shí)段的預(yù)期負(fù)載。3) 根據(jù)各個(gè)微服務(wù)新時(shí)段的預(yù)期負(fù)載計(jì)算其伸縮需求。4) 向容器編排平臺(tái)發(fā)送請(qǐng)求并執(zhí)行微服務(wù)伸縮操作。該流程的核心步驟為微服務(wù)預(yù)期負(fù)載的計(jì)算和微服務(wù)伸縮需求的計(jì)算。

圖5 基于負(fù)載關(guān)系圖的微服務(wù)自動(dòng)伸縮方法流程

4.2 微服務(wù)預(yù)期負(fù)載的計(jì)算

該過程的目的是借助系統(tǒng)的新舊時(shí)段入口微服務(wù)請(qǐng)求頻率變化幅度和微服務(wù)間負(fù)載關(guān)系來對(duì)各個(gè)微服務(wù)新時(shí)段預(yù)期負(fù)載進(jìn)行預(yù)估。該方法的執(zhí)行過程如算法1所示。該方法首先實(shí)時(shí)監(jiān)控系統(tǒng)入口微服務(wù)的請(qǐng)求頻率變化情況,計(jì)算自動(dòng)伸縮操作觸發(fā)前后入口微服務(wù)的請(qǐng)求頻率變化比值關(guān)系。接著,將入口微服務(wù)的舊負(fù)載乘以該比值作為入口微服務(wù)的新負(fù)載。由于入口微服務(wù)的新負(fù)載水平也會(huì)對(duì)其調(diào)用的微服務(wù)造成影響,接下來計(jì)算因?yàn)槿肟谖⒎?wù)負(fù)載變化而受到影響的微服務(wù)的預(yù)期負(fù)載變化,進(jìn)而逐個(gè)計(jì)算系統(tǒng)其他微服務(wù)的預(yù)期負(fù)載變化。如此往復(fù),最終得到整個(gè)系統(tǒng)中各個(gè)微服務(wù)在新時(shí)段的預(yù)期負(fù)載水平。

算法1計(jì)算微服務(wù)在新時(shí)段的預(yù)期負(fù)載強(qiáng)度

輸入:微服務(wù)負(fù)載關(guān)系圖中的微服務(wù)節(jié)點(diǎn)集V,微服務(wù)間負(fù)載關(guān)系集E。

輸出:每個(gè)微服務(wù)節(jié)點(diǎn)v和其預(yù)期新負(fù)載水平newLoadOfV。

1.forvinV

2.v.inbound=count(e∈Eande.to==v)

3.end for

4.將集合V中的所有入口微服務(wù)節(jié)點(diǎn)加入S

5.forsvcinS

6.定義svc與系統(tǒng)外部的負(fù)載關(guān)系為enterEdge,其伸縮操作觸發(fā)前后該系統(tǒng)外部請(qǐng)求頻率的比值為enterChange

7.enterEdge.newFlow=enterEdge.oldFlow*enterChange

8.end for

9.forsvcinS

10.oldLoad=0,newLoad=0

11.定義集合E中終點(diǎn)為svc的關(guān)系集為inboundEdges

12.foredgeininboundEdges

//計(jì)算該微服務(wù)新舊負(fù)載

13.oldLoad=oldLoad+edge.oldFlow

14.newLoad=newLoad+edge.newFlow

15.end for

16.map.put(svc,newLoad)

//該微服務(wù)的新時(shí)段預(yù)期負(fù)載

17.change=newLoad/newLoad

//計(jì)算該微服務(wù)新舊負(fù)載比值

18.定義集合E中起點(diǎn)為svc的關(guān)系集為outboundEdges

19.foredgeinoutboundEdges

//計(jì)算該微服務(wù)負(fù)載變化后,對(duì)

//其調(diào)用微服務(wù)的負(fù)載產(chǎn)生的影響

20.edge.newFlow=edge.oldFlow*change

21.svcTo=edge.to

22.svcTo.inbound=svcTo.inbound-1

23.ifsvcTo.inbound==0

24.S.add(svcTo)

25.end if

26.end for

27.end for

28.return map(v,newLoadOfV)

舉例如圖6所示,當(dāng)入口微服務(wù)A的外部請(qǐng)求頻率倍增時(shí),微服務(wù)A的負(fù)載也倍增,但其他各個(gè)微服務(wù)負(fù)載受到的影響各不相同。例如微服務(wù)C、E與微服務(wù)A聯(lián)系密切,因此負(fù)載均出現(xiàn)較大增長;但是由于微服務(wù)A較少調(diào)用微服務(wù)D,因此微服務(wù)D負(fù)載增長幅度不大;而微服務(wù)B并未參與到增長的請(qǐng)求的處理中去,因此該微服務(wù)的負(fù)載強(qiáng)度不發(fā)生變化。在這種情況下,只有微服務(wù)A、C、E需要伸縮,而微服務(wù)B、D基本無須伸縮。

圖6 微服務(wù)的負(fù)載強(qiáng)度變化示例

在計(jì)算得到各個(gè)微服務(wù)的負(fù)載強(qiáng)度后,下一步即可計(jì)算各個(gè)微服務(wù)的伸縮需求,調(diào)用容器編排平臺(tái)相應(yīng)接口執(zhí)行伸縮操作,并等待操作的完成。

4.3 微服務(wù)伸縮需求的計(jì)算

計(jì)算得到各個(gè)微服務(wù)在新時(shí)段預(yù)期負(fù)載強(qiáng)度后,即可借此計(jì)算各個(gè)微服務(wù)在新時(shí)段的實(shí)例需求數(shù),并在微服務(wù)容器編排平臺(tái)上執(zhí)行自動(dòng)伸縮操作并等待操作完成。本文假設(shè)對(duì)于某一個(gè)微服務(wù)上一系統(tǒng)穩(wěn)定時(shí)段的負(fù)載為Lold,上一時(shí)段該微服務(wù)實(shí)例數(shù)量為Nold;新時(shí)段該微服務(wù)預(yù)期負(fù)載為Lnew,預(yù)期新負(fù)載強(qiáng)度下的實(shí)例數(shù)量為Nnew。那么對(duì)于Nnew,本文采取如下計(jì)算方法:

(3)

通過計(jì)算得到在新時(shí)段各個(gè)微服務(wù)的預(yù)期的實(shí)例數(shù)量之后,即可調(diào)用容器編排平臺(tái)提供的相關(guān)接口,更新各個(gè)微服務(wù)的微服務(wù)實(shí)例數(shù)量配置信息,并等待其更新配置數(shù)據(jù)并部署或刪除指定數(shù)量的微服務(wù)實(shí)例。由于各個(gè)微服務(wù)的自動(dòng)伸縮是并行進(jìn)行的,因此最終耗費(fèi)的時(shí)間大致與伸縮耗時(shí)最長的微服務(wù)所需時(shí)間相同。

5 工具設(shè)計(jì)

基于前文所述的負(fù)載關(guān)系圖構(gòu)建方法和基于負(fù)載關(guān)系圖的微服務(wù)自動(dòng)伸縮方法,本文設(shè)計(jì)并實(shí)現(xiàn)工具LRGAS。該工具的實(shí)現(xiàn)架構(gòu)如圖7所示。該工具監(jiān)控和操作的目標(biāo)對(duì)象為部署于K8S集群上的微服務(wù)系統(tǒng)。對(duì)于目標(biāo)微服務(wù)系統(tǒng),微服務(wù)系統(tǒng)中還應(yīng)當(dāng)配合部署Zipkin調(diào)用鏈追蹤平臺(tái)和Prometheus指標(biāo)監(jiān)控平臺(tái)。目標(biāo)微服務(wù)系統(tǒng)部署在若干臺(tái)虛擬機(jī)組成的集群上,而LRGAS工具相關(guān)服務(wù)與數(shù)據(jù)庫部署在另一臺(tái)集群外的獨(dú)立虛擬機(jī)上,以防對(duì)微服務(wù)系統(tǒng)的運(yùn)行產(chǎn)生干擾。

圖7 LRGAS工具實(shí)現(xiàn)

LRGAS工具使用的外部數(shù)據(jù)共有兩種。其一是Zipkin調(diào)用鏈追蹤平臺(tái)收集的微服務(wù)系統(tǒng)請(qǐng)求調(diào)用鏈數(shù)據(jù)。每隔一段時(shí)間,本工具將會(huì)采集一次最新的調(diào)用鏈數(shù)據(jù),用于構(gòu)建和更新負(fù)載關(guān)系圖中的數(shù)據(jù)。其二是Prometheus監(jiān)控平臺(tái)提供的監(jiān)控指標(biāo)數(shù)據(jù)。這部分?jǐn)?shù)據(jù)一方面用于監(jiān)控入口微服務(wù)的請(qǐng)求頻率變化,另一方面用于判斷各個(gè)微服務(wù)的監(jiān)控指標(biāo)是否處于預(yù)設(shè)閾值范圍內(nèi),并最終用于判定是否觸發(fā)微服務(wù)的自動(dòng)伸縮操作。

該工具主要包括三個(gè)Java服務(wù)和一個(gè)圖數(shù)據(jù)庫。三個(gè)服務(wù)均基于Spring Boot框架完成開發(fā)。數(shù)據(jù)收集與處理服務(wù)實(shí)現(xiàn)負(fù)責(zé)關(guān)系圖的構(gòu)建和維護(hù),定時(shí)從Zipkin平臺(tái)抽取調(diào)用鏈數(shù)據(jù)并將更新的負(fù)載關(guān)系圖發(fā)送到圖數(shù)據(jù)庫API服務(wù)。圖數(shù)據(jù)API服務(wù)對(duì)接neo4j圖數(shù)據(jù)庫,負(fù)責(zé)負(fù)載關(guān)系圖數(shù)據(jù)的讀取和存儲(chǔ)。自動(dòng)伸縮服務(wù)從Prometheus平臺(tái)實(shí)時(shí)抽取各個(gè)微服務(wù)的監(jiān)控指標(biāo)數(shù)據(jù),判斷自動(dòng)伸縮操作是否觸發(fā)。若自動(dòng)伸縮操作被觸發(fā),自動(dòng)伸縮服務(wù)從圖數(shù)據(jù)庫API服務(wù)獲取最新的微服務(wù)負(fù)載關(guān)系圖,計(jì)算出各個(gè)微服務(wù)的伸縮需求后,向K8S平臺(tái)發(fā)出伸縮指令,并等待操作的完成。

6 實(shí) 驗(yàn)

6.1 實(shí)驗(yàn)過程

本實(shí)驗(yàn)使用部署在Kubernetes容器編排平臺(tái)上的TrainTicket開源微服務(wù)基準(zhǔn)系統(tǒng)作為實(shí)驗(yàn)對(duì)象。TrainTicket使用的是在工業(yè)界生產(chǎn)環(huán)境中使用較多的Spring Cloud Sleuth[22]與Zipkin[23]進(jìn)行調(diào)用鏈日志的收集,可以很好地模擬微服務(wù)系統(tǒng)在真正生產(chǎn)環(huán)境中的運(yùn)行狀況。

在TrainTicket的眾多功能中,本文選取了三種涉及不同規(guī)模微服務(wù)數(shù)量且在實(shí)際使用中使用較為頻繁的場(chǎng)景,如表1所示。場(chǎng)景1模擬的是單一微服務(wù)需要伸縮的場(chǎng)景,對(duì)應(yīng)于TrainTicket系統(tǒng)的登錄場(chǎng)景。該場(chǎng)景模擬用戶登錄高峰期,涉及驗(yàn)證碼請(qǐng)求與核對(duì)等操作。在該場(chǎng)景下大量用戶登錄導(dǎo)致對(duì)于驗(yàn)證碼服務(wù)的請(qǐng)求數(shù)量激增。此處涉及一個(gè)微服務(wù),即驗(yàn)證碼服務(wù)。場(chǎng)景2模擬的是有較多微服務(wù)需要伸縮的場(chǎng)景,對(duì)應(yīng)于TrainTicket系統(tǒng)出現(xiàn)大量用戶訂票場(chǎng)景。該場(chǎng)景模擬用戶火車票預(yù)訂高峰期,包括余票查詢、價(jià)格計(jì)算、訂單創(chuàng)建和通知發(fā)送等請(qǐng)求。該場(chǎng)景是TrainTicket系統(tǒng)中最為復(fù)雜的場(chǎng)景,需要9~15個(gè)微服務(wù)協(xié)同完成該功能。場(chǎng)景3模擬的是中等數(shù)量微服務(wù)需要伸縮的場(chǎng)景。該場(chǎng)景模擬用戶退票高峰期,包含訂單狀態(tài)修改、退款等操作。該場(chǎng)景是一個(gè)中等復(fù)雜的功能,包括訂單狀態(tài)修改、退款等操作,涉及5~7個(gè)微服務(wù)。由于微服務(wù)負(fù)載強(qiáng)度會(huì)影響請(qǐng)求響應(yīng)時(shí)間,因此本實(shí)驗(yàn)以請(qǐng)求響應(yīng)時(shí)間為自動(dòng)伸縮監(jiān)控指標(biāo)。對(duì)于三種場(chǎng)景,實(shí)驗(yàn)將入口微服務(wù)的請(qǐng)求頻率變?yōu)檎_\(yùn)行下的3倍,以觸發(fā)自動(dòng)伸縮操作。

表1 自動(dòng)伸縮場(chǎng)景列表

為了使負(fù)載關(guān)系圖收集到完整且全面的數(shù)據(jù),在觸發(fā)自動(dòng)伸縮操作前,應(yīng)先維持系統(tǒng)正常運(yùn)行一段時(shí)間。本實(shí)驗(yàn)實(shí)現(xiàn)了一個(gè)簡單的請(qǐng)求模擬器,以設(shè)定頻率向微服務(wù)系統(tǒng)發(fā)送各種類型請(qǐng)求。請(qǐng)求的頻率會(huì)隨著時(shí)間產(chǎn)生小幅變化,以模擬微服務(wù)系統(tǒng)在實(shí)際應(yīng)用中運(yùn)行狀況。

本文實(shí)驗(yàn)主要通過對(duì)比微服務(wù)系統(tǒng)在不同的場(chǎng)景下使用傳統(tǒng)的各個(gè)微服務(wù)獨(dú)立自動(dòng)伸縮的方法以及基于負(fù)載關(guān)系圖的自動(dòng)伸縮算法最終完全適應(yīng)新的負(fù)載并達(dá)到穩(wěn)態(tài)(也就是微服務(wù)實(shí)例數(shù)量不再變化)的時(shí)間,來驗(yàn)證本文方法的高效性。實(shí)驗(yàn)按照?qǐng)鼍胺譃槿M。對(duì)于每組實(shí)驗(yàn),使用請(qǐng)求模擬器模擬系統(tǒng)一段時(shí)間的正常運(yùn)行,以確保微服務(wù)系統(tǒng)的負(fù)載依賴圖收集到足夠的數(shù)據(jù)。然后,依照各個(gè)場(chǎng)景的描述,逐步增加對(duì)應(yīng)場(chǎng)景功能的請(qǐng)求頻率以增加對(duì)應(yīng)微服務(wù)的負(fù)載。當(dāng)負(fù)載增大到一定程度時(shí),自動(dòng)伸縮操作將會(huì)被觸發(fā)。本實(shí)驗(yàn)將會(huì)記錄從自動(dòng)伸縮操作的觸發(fā)到整個(gè)系統(tǒng)最終完成全部操作的時(shí)間。對(duì)于每種場(chǎng)景,本文將會(huì)進(jìn)行3次實(shí)驗(yàn),并取平均值作為最終結(jié)果。

6.2 實(shí)驗(yàn)結(jié)果與分析

本次實(shí)驗(yàn)的最終實(shí)驗(yàn)結(jié)果數(shù)據(jù)如表2所示。本實(shí)驗(yàn)對(duì)三個(gè)場(chǎng)景分別使用兩種自動(dòng)伸縮方法的所需平均時(shí)間折線圖如圖8所示。

表2 自動(dòng)伸縮實(shí)驗(yàn)結(jié)果統(tǒng)計(jì)表

續(xù)表2

圖8 兩種自動(dòng)伸縮方法使用時(shí)間對(duì)比

根據(jù)圖8中的數(shù)據(jù)可以得出,在微服務(wù)數(shù)量較少時(shí),本文所述的自動(dòng)伸縮方法沒有優(yōu)化效果,甚至有時(shí)耗時(shí)高于各個(gè)微服務(wù)獨(dú)立伸縮的方法。但在自動(dòng)伸縮的微服務(wù)數(shù)量逐漸增加時(shí),本文方法逐漸體現(xiàn)出時(shí)間上的優(yōu)勢(shì)。這是由于在微服務(wù)規(guī)模增大的情況下,微服務(wù)之間的依賴關(guān)系也變得更加復(fù)雜。使用傳統(tǒng)的微服務(wù)伸縮方法在微服務(wù)數(shù)量規(guī)模較大且調(diào)用關(guān)系又復(fù)雜的情況下,很容易在一個(gè)微服務(wù)擴(kuò)容后,流量瓶頸迅速轉(zhuǎn)移到另一個(gè)微服務(wù)上,進(jìn)而引發(fā)另一輪擴(kuò)容操作,如此多輪后最終完成擴(kuò)容。而在僅有少量或一個(gè)微服務(wù)需要擴(kuò)容時(shí),無論使用何種方法都只需一輪即可完成所有伸縮操作,而本文方法還需要額外進(jìn)行各個(gè)微服務(wù)需求的計(jì)算操作,反而會(huì)浪費(fèi)一些時(shí)間。根據(jù)測(cè)算,根據(jù)微服務(wù)負(fù)載依賴圖計(jì)算各個(gè)微服務(wù)伸縮需求的時(shí)間大約在2~3 s左右。此外,由于本文所提出的自動(dòng)伸縮方法一并完成所有微服務(wù)的伸縮,導(dǎo)致在同一時(shí)刻有更多微服務(wù)實(shí)例處于正在調(diào)度和啟動(dòng)狀態(tài),在實(shí)際系統(tǒng)運(yùn)行中這將會(huì)拖慢單個(gè)微服務(wù)實(shí)例的啟動(dòng)時(shí)間,但總體上來說由于伸縮操作的并行性,本文方法仍然相比傳統(tǒng)方法能節(jié)省大量時(shí)間。

7 結(jié) 語

目前微服務(wù)架構(gòu)已經(jīng)在企業(yè)實(shí)踐中得到了廣泛的應(yīng)用。然而,獨(dú)立地對(duì)各個(gè)微服務(wù)進(jìn)行監(jiān)測(cè)的自動(dòng)伸縮方法存在微服務(wù)系統(tǒng)內(nèi)部負(fù)載瓶頸轉(zhuǎn)移的問題,使得系統(tǒng)適應(yīng)新負(fù)載所耗費(fèi)的時(shí)間較長。針對(duì)上述挑戰(zhàn),本文提出基于負(fù)載關(guān)系圖的微服務(wù)故障自動(dòng)伸縮方法。首先,本文設(shè)計(jì)和定義微服務(wù)負(fù)載關(guān)系圖的結(jié)構(gòu),并介紹了圖譜的數(shù)據(jù)抽取方式和數(shù)據(jù)示例。接著,本文借助微服務(wù)間負(fù)載關(guān)系圖,在系統(tǒng)外部負(fù)載發(fā)生變化后,分析各個(gè)微服務(wù)的負(fù)載強(qiáng)度變化,進(jìn)而計(jì)算各個(gè)微服務(wù)的伸縮需求,最后向容器編排平臺(tái)發(fā)出伸縮指令并完成操作?;谇拔乃龇椒ǎ疚脑O(shè)計(jì)并實(shí)現(xiàn)了工具LRGAS。最后,本文使用TrainTicket開源微服務(wù)基準(zhǔn)系統(tǒng)開展了伸縮方法對(duì)比實(shí)驗(yàn)。實(shí)驗(yàn)結(jié)果表明,隨著微服務(wù)數(shù)量的增加,本文方法的高效性體現(xiàn)愈加明顯。

本文方法目前也存在一些不足。本文自動(dòng)伸縮方法在監(jiān)控指標(biāo)超出門限值范圍時(shí)才會(huì)觸發(fā),使得入口微服務(wù)的自動(dòng)伸縮操作存在滯后性。未來可以引入機(jī)器學(xué)習(xí)方法對(duì)微服務(wù)系統(tǒng)的負(fù)載走勢(shì)進(jìn)行預(yù)測(cè),在請(qǐng)求頻率大幅變化前即觸發(fā)伸縮操作,以更快適應(yīng)新的負(fù)載強(qiáng)度。

猜你喜歡
調(diào)用實(shí)例監(jiān)控
通信電源監(jiān)控系統(tǒng)在電力通信中的應(yīng)用
基于Android Broadcast的短信安全監(jiān)聽系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)
GPS/DR/GIS技術(shù)在基于GSM—R列車監(jiān)控系統(tǒng)中應(yīng)用
偵察兵
完形填空Ⅱ
完形填空Ⅰ
利用RFC技術(shù)實(shí)現(xiàn)SAP系統(tǒng)接口通信
C++語言中函數(shù)參數(shù)傳遞方式剖析
1-Wire在家庭監(jiān)控網(wǎng)絡(luò)中的應(yīng)用