楊怡濱 楊 偉 于新容 丘偉森
(廣東省輕工業(yè)高級技工學校信息工程系 廣東 廣州 510315)
服務網(wǎng)格[1]是致力于解決服務間通信的基礎設施層,負責在構成復雜應用系統(tǒng)的微服務間靈活、高效和可靠地傳遞請求,用于控制和監(jiān)視微服務應用的內(nèi)部、服務到服務的通信。
服務網(wǎng)格由數(shù)據(jù)面和控制面組成,其中控制面用于集中設置相關策略進行服務間交互的流量監(jiān)控與控制策略實施,而數(shù)據(jù)面則由一組輕量級網(wǎng)絡代理(簡稱邊車代理)構成。邊車代理是一個輔助進程,它與主應用程序一起運行,并為其提供額外的功能。每個服務都配備了一個邊車代理,它們與微服務一起部署用來實現(xiàn)(即邊車部署模式)服務間的交互。
服務網(wǎng)格將服務間通信從底層的基礎設施中分離出來使得服務能夠被監(jiān)控、托管和控制,同時為服務運行時提供統(tǒng)一的、應用層面的可見性和可控性,因此有效解決了大規(guī)模微服務服務治理問題。
目前服務網(wǎng)格技術仍處于發(fā)展階段,性能是服務網(wǎng)格面臨的核心問題和挑戰(zhàn)[2]。服務網(wǎng)格(尤其是邊車代理)的加入會增加請求調(diào)用鏈路的長度,因此必然會帶來性能的損耗。眾所周知,服務架構多用于分布式互聯(lián)網(wǎng)系統(tǒng)應用中,而來自客戶端的高并發(fā)訪問請求(如車票預訂、搶紅包、雙十一購物節(jié)等場景)十分常見,在使用服務網(wǎng)格后,并發(fā)壓力從應用層服務轉移到服務網(wǎng)格層面。因此,如何使服務網(wǎng)格具備高性能的、異步無阻塞的通信交互能力十分重要。本文分析發(fā)現(xiàn),影響服務網(wǎng)格整體性能的主要因素如下:(1) 服務網(wǎng)格數(shù)據(jù)面中的邊車代理負責服務間通信,在代理請求、向外轉發(fā)請求和回傳響應三個關鍵步驟涉及大量網(wǎng)絡IO和計算,在高并發(fā)場景下使用大量線程資源,頻繁的線程切換會嚴重影響并發(fā)性能。(2) 服務間及邊車代理間交互通?;贖TTP協(xié)議,而傳統(tǒng)的HTTP協(xié)議具有固定的消息格式,其中可能包含冗余的數(shù)據(jù),其次HTTP協(xié)議基于TCP協(xié)議,因此每次請求建立連接時都經(jīng)歷三次握手,在高并發(fā)的場景下可能會造成明顯的延遲。
針對上述問題,本文提出了面向服務網(wǎng)格的性能優(yōu)化方法,首先基于Reactor模式[3],同時結合線程和協(xié)程[4]兩者的計算優(yōu)勢,設計了一種具有高并發(fā)處理能力的計算模型,并將其用于邊車代理的設計實現(xiàn);其次基于HTTP協(xié)議設計了一種輕量、高效的應用層交互協(xié)議,用以減少服務邊車代理間通信時傳輸?shù)臄?shù)據(jù)量,同時實現(xiàn)了基于零拷貝技術[5]的協(xié)議消息編解碼算法,可以顯著提高通信能力。
本文基于上述技術設計實現(xiàn)了一個原型系統(tǒng),并通過實驗與當前主流的服務網(wǎng)格系統(tǒng)Linkerd和Envoy進行了對比。實驗分別從并發(fā)性能和通信性能兩方面進行分析比較,結果表明本文提出的優(yōu)化方法使得服務網(wǎng)格系統(tǒng)在減少響應時間和網(wǎng)絡傳輸數(shù)據(jù)量兩方面均有顯著的性能提升。
服務網(wǎng)格是近兩年興起的技術,其相關研究目前較少,但是已經(jīng)得到了工業(yè)界的廣泛關注和應用。Linkerd和Envoy是目前典型的服務網(wǎng)格系統(tǒng),Linkerd從2016年到2018年圍繞性能優(yōu)化發(fā)布了1.0.x、1.1.x、1.2.x、1.3.x、1.4.x、1.5.x、1.6.x等版本,嘗試使用最新版本的Finagle框架優(yōu)化、使用GraalVM提高性能、通過Open J9 JVM的支持降低40%的內(nèi)存占用并大幅降低長尾延遲,目前GraalVM性能優(yōu)化方案失敗,僅存Open J9 JVM的優(yōu)化版本,其測試版本還在繼續(xù)發(fā)行。Envoy在2017年到2018年發(fā)布了1.2.x、1.3.x、1.4.x、1.5.x、1.6.x、1.7.x、1.8.x等版本,從多線程加非阻塞異步IO計算模型、通信協(xié)議優(yōu)化和熱重啟等方面進行了優(yōu)化設計。
國內(nèi)自2017年底大規(guī)模開展高性能服務網(wǎng)格技術的研發(fā),其中:華為用Go語言在路由管理、多協(xié)議支持方面做優(yōu)化,自行開發(fā)了Mesher;螞蟻金服從IO、協(xié)議、調(diào)度策略方面對服務網(wǎng)格進行了優(yōu)化并開發(fā)了SOFAMesh;新浪開發(fā)的WeiboMesh在通信方面提供HTTP Mesh方案,支持HTTP與RPC服務之間的交互。但是,服務網(wǎng)格的加入增加了請求調(diào)用鏈路的長度,必然帶來性能的損耗,例如:阿里巴巴對基于Envoy自主開發(fā)的Dubbo Mesh進行測試,發(fā)現(xiàn)Dubbo Mesh的每一次請求轉發(fā)會造成1.5 ms的延時。
與上述工作不同,本文主要從并發(fā)處理模型和服務網(wǎng)格數(shù)據(jù)傳輸兩方面提出性能優(yōu)化的方法。
基于線程的并發(fā)和事件驅動是并發(fā)處理的兩種基本方法。迄今為止,事件驅動的并發(fā)方法因其更高的性能和更好的可伸縮性而得到更為廣泛的應用。Reactor模式是當前具有代表性的事件驅動的并發(fā)處理模式之一,常用于具有高并發(fā)需求的客戶端-服務器系統(tǒng)的設計和實現(xiàn)中,許多流行的開源框架和服務器系統(tǒng)均基于Reactor模式,如Netty、Redis和Node.js等。
Reactor模式[3]稱為反應器模式,是一種為處理并發(fā)服務請求,并將請求提交到一個或者多個服務處理程序的事件驅動并發(fā)處理設計模式。當客戶端請求抵達后,服務處理程序使用多路分配策略,由一個非阻塞線程來接收所有的請求,然后派發(fā)這些請求至相關的工作線程進行處理。Reactor模式主要包含如下四部分內(nèi)容。
(1) 初始事件分發(fā)器(Initialization Dispatcher)用于管理事件處理器(Event Handler),負責定義注冊、移除事件處理器等。當服務請求到達時,它根據(jù)事件發(fā)生的Handle將其分發(fā)給對應的事件處理器進行處理。
(2) 同步(多路)事件分離器(Synchronous Event Demultiplexer)無限循環(huán)等待新事件的到來,一旦發(fā)現(xiàn)有新的事件到來,就會通知初始事件分發(fā)器去調(diào)取特定的事件處理器。
(3) 系統(tǒng)處理程序(Handles)是操作系統(tǒng)中的句柄,是對資源在操作系統(tǒng)層面上的一種抽象,它可以是打開的文件、一個連接(Socket)、時鐘等。由于Reactor模式一般使用在網(wǎng)絡編程中,因而這里一般指Socket Handle,即一個網(wǎng)絡連接(Connection Channel)注冊到同步(多路)事件分離器中,以監(jiān)聽Handle中發(fā)生的事件,包括網(wǎng)絡連接事件、讀/寫和關閉事件等。
(4) 事件處理器(Event Handler)用來定義事件處理方法,以供初始事件分發(fā)器回調(diào)使用。
對于高并發(fā)系統(tǒng),常會使用Reactor模式,其代替了常用的多線程處理方式,節(jié)省了系統(tǒng)的資源,提高了系統(tǒng)的吞吐量。由于服務網(wǎng)格系統(tǒng)作為服務間交互的基礎設施層常常面臨服務請求與響應的高并發(fā)場景,因此本文選擇基于Reactor模式進行服務網(wǎng)格中邊車代理并發(fā)處理模型的設計。本文對Reactor模式進行了擴展,結合線程和協(xié)程的各自優(yōu)勢,實現(xiàn)由Manager、Worker和Collaborator三類角色協(xié)同的高并發(fā)處理機制。
服務網(wǎng)格的典型工作模式如圖1所示。以單方面的Microservice A的視角為例:Microservice A的服務網(wǎng)格組件邊車(Mesh A)代理Microservice A對Microservice B的網(wǎng)絡通信,Mesh A一方面需要維護與Microservice A的連接,另一方面需要將Microservice A的請求數(shù)據(jù)轉發(fā)給Microservice B(Microservice B的網(wǎng)絡通信由Mesh B代理),然后Mesh A收到響應并回傳給Microservice A。
圖1 服務網(wǎng)格工作模式
在Microservice A通信的過程中,Mesh A充當了類似“Server”與“Client”的角色,其中的計算過程可以分解成代理請求、向外轉發(fā)請求和回傳響應三個關鍵步驟。由于Reactor模型通常用于服務器端的設計,而每個服務網(wǎng)格的組件邊車代理在圖1所示的工作模式中都會承擔“Server”的角色,基于這一觀察分析,本文提出了基于Reactor模式的并發(fā)計算模型,用于設計構成服務網(wǎng)格數(shù)據(jù)面的邊車代理。
如圖2所示,該模型分為Manager、Worker和Collaborator三種角色。Manager以線程作為計算實體運行,用于維護服務的連接及分發(fā)連接的網(wǎng)絡事件給Worker;Worker同樣以線程作為計算實體運行,Worker執(zhí)行相關數(shù)據(jù)計算的任務,然后通過Collaborator向外轉發(fā)請求;Collaborator以協(xié)程作為計算實體運行,轉發(fā)請求并等待、計算、處理和回傳響應。由圖2可以看出Manager和Worker基于Reactor模式,而Collaborator則是在Reactor模式上的進一步擴展。
圖2 基于Reactor的高并發(fā)計算模型
Manager和Worker基于Reactor模式設計實現(xiàn),傳統(tǒng)的順序編程采用每條指令依次執(zhí)行的方式,難以滿足高性能的需求。Reactor模式是基于數(shù)據(jù)流和變化傳遞的聲明式的編程范式,用消息發(fā)送的事件流驅動機制取代傳統(tǒng)的順序執(zhí)行機制[6]。Manager和Worker服務的請求數(shù)據(jù)作為數(shù)據(jù)流,Manager建立、維護相關連接后不會阻塞消息處理,Manager會監(jiān)聽各種網(wǎng)絡事件并分發(fā)給相應的Worker進行處理。
服務網(wǎng)格啟動時,綁定操作系統(tǒng)的某個端口后,首先將套接字(Socket)注冊到Manager線程的選擇器(Selector)上。Manager負責維護連接上下文的一致性,通過Selector監(jiān)聽客戶端的TCP連接請求,并將消息的數(shù)據(jù)流事件循環(huán)(EventLoop)調(diào)度給相應的Worker進行處理。Worker負責消息的讀取、解碼、編碼和發(fā)送,Worker采用串行化設計,1個Worker線程可以同時處理N條鏈路連接,1條鏈路只對應1個Worker線程,通過串行化設計有效防止并發(fā)操作問題。
隨后,Worker和Collaborator協(xié)作,應用于服務網(wǎng)格向外轉發(fā)請求和回傳響應的場景。Worker通過scheduler調(diào)度器調(diào)度Collaborator執(zhí)行任務,Collaborator協(xié)程執(zhí)行完任務后會動態(tài)從其他的任務隊列偷取任務執(zhí)行。Collaborator負責請求轉發(fā)和響應回傳等任務,ClientChannel是轉發(fā)請求時與目標服務的連接管道,Messenger執(zhí)行ClientChannel的讀、寫、解碼、編碼、轉發(fā)等,ServerChannel是與代理服務的連接,Messenger回傳響應時,將數(shù)據(jù)寫入ServerChannel。與Worker不同,1個Collaborator處理1條鏈路連接,1個鏈路對應1個Collaborator協(xié)程。Collaborator由Worker觸發(fā)scheduler調(diào)度,Worker的事件循環(huán)組可包含多個事件循環(huán),每個事件循環(huán)包含1個選擇器和1個事件循環(huán)線程,每個事件循環(huán)線程通過事件機制向scheduler調(diào)度器調(diào)度Collaborator。
Collaborator基于協(xié)程實現(xiàn)。對比線程,協(xié)程有以下優(yōu)勢:(1) 更好地利用CPU資源,沒有類似線程調(diào)度的上下文切換;(2) 更好地利用內(nèi)存資源,用戶只需要分配合適的空間即可。因此能夠避免頻繁的線程切換和由此導致的因CPU緩存行失效引起的性能下降問題。
為了減少服務網(wǎng)格中代理間傳輸?shù)臄?shù)據(jù)量,減輕網(wǎng)絡負載,本文基于HTTP協(xié)議進行了通信協(xié)議的定制化,設計了輕量化的協(xié)議和相應的編解碼算法,能夠有效降低服務代理交互的通信數(shù)據(jù)量,提高編解碼速率。
如圖3所示,定制化協(xié)議的結構由固定長度的消息頭Head(8字節(jié))和不定長度的消息體組成,具體組成如下:Magic Number:表示是否該協(xié)議的數(shù)據(jù)包;Serial ID:表示標志請求的序列號;Event Type:表示事件類型,1表示心跳消息,0表示不是心跳消息;Response:返回數(shù)據(jù),0表示服務端可以不作應答,1表示服務端必須應答消息;Message Type:表示請求或響應的消息狀態(tài);Response Code:請求響應狀態(tài)碼,200表示成功,400表示失敗,每種狀態(tài)碼對應相關原因;Message Length:表示消息長度;Message Body:表示消息數(shù)據(jù)。
圖3 定制化協(xié)議數(shù)據(jù)結構
本文設計的編解碼算法主要解決網(wǎng)絡傳輸過程中出現(xiàn)的半包/粘包問題,同時基于零拷貝技術有效減少操作系統(tǒng)內(nèi)核態(tài)切換用戶態(tài)過程的性能損失。
如圖4所示,客戶端發(fā)送Msg1和Msg2兩個數(shù)據(jù)包給服務端,網(wǎng)絡通信過程中會出現(xiàn)以下問題:(1) 無半包、無粘包,即服務端依次收到兩個獨立完整的數(shù)據(jù)包;(2) 半包,即服務端收到一個數(shù)據(jù)包,數(shù)據(jù)包只包含了Msg1的一部分;(3) 粘包,即服務端收到一個數(shù)據(jù)包,數(shù)據(jù)包包含了兩個請求的數(shù)據(jù)。
圖4 半包和粘包
基于上述情況,本文設計了一個基于計數(shù)的可彈性伸縮的鏈式數(shù)據(jù)結構BufferLinkList,用以緩存網(wǎng)絡交互數(shù)據(jù),并進行編解碼。BufferLinkList底層是循環(huán)鏈表,由Buffer塊構成,Buffer塊封裝了直接內(nèi)存,可以指定大小,默認為64字節(jié),RefCnt表示Buffer的引用計數(shù),通過引用計數(shù),系統(tǒng)會自動進行垃圾回收。BufferLinkList能夠彈性伸縮,如果數(shù)據(jù)過多,BufferLinkList會自動擴容,如果數(shù)據(jù)過少,會自動縮容。基于BufferLinkList的零拷貝體現(xiàn)在以下方面:(1) 在直接內(nèi)存里面分配空間,而不是在堆內(nèi)存中分配;(2) BufferLink-List會自動增減Buffer塊,對上層提供統(tǒng)一讀寫接口,避免了數(shù)據(jù)的拷貝。BufferLinkList的數(shù)據(jù)結構如圖5所示。
圖5 BufferLinkList數(shù)據(jù)結構
編碼時,首先計算數(shù)據(jù)包的大?。蝗缓蟾鶕?jù)協(xié)議數(shù)據(jù)結構編碼并存儲到BufferLinkList中;最后通知操作系統(tǒng)發(fā)送網(wǎng)絡數(shù)據(jù)。編碼算法如算法1所示。
算法1編碼算法
輸入:data。
輸出:bufferLinkList。
1. size←caculateSize(data)
//計算數(shù)據(jù)包大小
2. bufferLinkList←ButfferLinkListPool.getBufferLinkList(size)
//申請鏈表
3. header←HeaderTemplate.getHeader()
//從模板初始化頭部數(shù)據(jù)
4. header.setMagic(MAGIC)
//用戶自定義配置
5. header.setld(ID)
6. header.setlsHeartBeat(false)
7. head.setLength(data,length)
8. ……
9. bufferLinkList.write(head,data)
//寫入數(shù)據(jù)
10. bufferLinkList.setRefCnt(1)
11.returnbufferLinkList
EndFunction
解碼時,首先用BufferLinkList緩存操作系統(tǒng)收到的網(wǎng)絡數(shù)據(jù);然后根據(jù)已緩存數(shù)據(jù)的大小判斷是否滿足Head解碼階段,如果滿足則進入Head解碼,如果不滿足則繼續(xù)緩存;完成Head解碼后計算消息的長度并進入Body解碼狀態(tài),如果網(wǎng)絡數(shù)據(jù)大于等于消息長度則執(zhí)行完解碼過程,并對已解碼的數(shù)據(jù)重置引用計數(shù),否則繼續(xù)緩存,等待下一個Body解碼狀態(tài)。解碼算法如算法2所示。
算法2解碼算法
輸入:bufferLinkList。
輸出:data。
1. decodeStat←State.Head
//初始化解碼狀態(tài)
2. length←0
3.whilebufferLinkList←receive_data()do
4.ifdecodeState==State.Headthen
//判斷解碼階段
5.ifbufferLinkList.size()<32then
6.continue
//數(shù)據(jù)不足,跳出
7.else
8. length←bufferLinkList.getDataBodyLength()
9. decodeState←State.Body
//進入Body解碼階段
10.ifbufferLinkList.size() -32>=lengththen
11.gotoGetData
12.else
13.continue
14.endif
15.endif
16.elseifdecodeState==State.Body
17.ifbufferLinkList.size() -32 18.continue //數(shù)據(jù)不足,跳出 19.else 20. GetData: data←bufferLinkList.getData(length) //獲取數(shù)據(jù)體 21. endIndex←bufferLinkL ist.startIndex+length+32 //應用計數(shù)重置 22. bufferLinkList.setRefCnt(startIndex,endIndex,0) 23. bufferLinkList.setStartIndex(endlndex) //指正清零 24.returndata 25.endif 26.endif 27.endwhile EndFunction 基于上述關鍵技術,本文基于Java 8設計實現(xiàn)了一個原型系統(tǒng)如圖6所示。整個系架構采用分層模型設計,包括核心層、計算層、應用層。 圖6 原型系統(tǒng)總體架構 1) 核心層:包括BufferLinkListPool和統(tǒng)一通信接口。BufferLinkListPool提供BufferLinkList,BufferLinkList是封裝了直接內(nèi)存的鏈式結構,用于緩存網(wǎng)絡IO數(shù)據(jù),支持基于計數(shù)的垃圾回收,并且彈性可伸縮;統(tǒng)一通信API層提供了基于BufferLinkList的通信相關的操作接口。 2) 計算層:提供了以線程封裝的Manager、Worker等計算資源及用協(xié)程封裝的Messenger計算資源,基于本文提出的并發(fā)處理模型提供高并發(fā)處理能力。 3) 應用層:實現(xiàn)了服務網(wǎng)格的核心服務,如:服務注冊與發(fā)現(xiàn)服務、協(xié)議與編解碼服務、路由選取服務等。 網(wǎng)絡數(shù)據(jù)進入服務網(wǎng)格后的處理流程包括以下步驟:(1) 網(wǎng)絡數(shù)據(jù)從物理網(wǎng)卡進入,操作系統(tǒng)陷入內(nèi)核態(tài)處理;(2) 服務網(wǎng)格從BufferLinkListPool獲取BufferLinkList,并緩存IO數(shù)據(jù);(3) 使用反應式編程的BWM計算模型的計算資源,Manager線程維護連接,并向Worker線程分發(fā)任務;(4) Worker線程通過統(tǒng)一通信API處理相關數(shù)據(jù),如編解碼,然后分發(fā)給Collaborator協(xié)程,并重新編碼向外轉發(fā);(5) Collaborator收到請求后回傳給代理服務。 為了評價本文方法的有效性,本節(jié)首先設計相關實驗,將原型系統(tǒng)(簡稱BWM)與目前主流服務網(wǎng)格系統(tǒng)Linkerd(1.6版本)和Envoy(1.8版本)在相同環(huán)境下進行性能測試。實驗環(huán)境基于2臺阿里云服務器搭建,每臺服務器配置信息如圖7所示,并根據(jù)實驗結果進行分析對比。 圖7 實驗環(huán)境設計 實驗由施壓方和受壓方組成,施壓方Benchmarker會產(chǎn)生三組高并發(fā)連接(128并發(fā)連接、256并發(fā)連接和512并發(fā)連接)向Cosumer服務進行壓測,Benchmarker生成隨機的字符串data并發(fā)送請求給Cosumer服務,Cosumer服務收到該請求后會通過服務網(wǎng)格將data發(fā)給Provider服務的服務網(wǎng)格,Provider服務的服務網(wǎng)格將data發(fā)給Provider服務,Provider服務計算data的HashCode后將HashCode(data)通過服務網(wǎng)格返回Cosumer服務的服務網(wǎng)格,Cosumer服務的服務網(wǎng)格將響應返回給Cosumer服務,Cosumer服務最后將結果返回給Benchmarker校驗并統(tǒng)計相關性能指標。 實驗時每一組壓力測試持續(xù)時間60 s,運行10次,去掉最好和最差的實驗數(shù)據(jù),最終的實驗數(shù)據(jù)取平均值。實驗流程如下: (1) 每輪評測在受壓方中啟動五個服務(以Docker實例的形式啟動),一個ETCD服務作為注冊表、一個Consumer服務和三個Provider服務,每個服務都會綁定服務網(wǎng)格,Provider服務會Sleep(50 ms)模擬計算時間; (2) 使用另一臺獨立的服務器作為施壓方,分不同壓力場景對Consumer服務進行壓力測試,得到相關性能指標; (3) ETCD是注冊中心服務,用來存儲服務注冊信息;Provider是服務提供者,Consumer是服務消費者,Consumer消費Provider提供的服務。 為了盡可能模擬真實情況,每個服務實例所占用的系統(tǒng)資源各不相同,運行Consumer服務及其Service Mesh的實例(為了便于描述,下文將簡稱為Consumer實例,Provider實例類似)占用的系統(tǒng)資源是最多的,而三個Provider實例占用的系統(tǒng)資源總和與Consumer實例占用的系統(tǒng)資源是相同的,并且Provider實例按照small ∶medium ∶large=1 ∶2 ∶3的比例進行分配,分為Provider(small)實例、Provider(medium)實例和Provider(large)實例,服務實例的資源分配如表1所示。 表1 服務實例資源分配 在每個Consumer和Provider實例中,都存在一個服務網(wǎng)格實例,其在整個系統(tǒng)中起到了非常關鍵的作用。 (1) Consumer服務是基于Spring Cloud實現(xiàn)的Web應用,會發(fā)送請求給Provider服務,服務之間數(shù)據(jù)傳遞是通過服務網(wǎng)格進行的,服務網(wǎng)格的性能決定了系統(tǒng)的性能;(2) 任何一個Provider實例的性能都是小于Consumer實例的,服務實例的調(diào)度選取策略意義重大;(3) Provider實例最高支持200并發(fā)的連接,高并發(fā)下會產(chǎn)生回壓問題。 實驗使用wrk作為施壓方,wrk是一個基于事件機制的高性能HTTP壓力測試工具,能用很少的線程產(chǎn)生極高的訪問壓力。實驗統(tǒng)計性能測試指標如表2所示。 表2 性能測試指標 4.3.1并發(fā)性能分析 為了評價本文提出的并發(fā)模型對于提高服務網(wǎng)格并發(fā)性能的有效性,本文設計相關實驗與目前主流的服務網(wǎng)格系統(tǒng)Linkerd和Envoy進行比較,在相同實驗條件下,用wrk測試三者的性能表現(xiàn)。 實驗結果顯示本文原型系統(tǒng)和Envoy(C++實現(xiàn))有非常相似的表現(xiàn),兩者性能都明顯優(yōu)于Linkerd。詳細結果如表3-表5所示,從延時分布上分析,并發(fā)連接從128并發(fā)連接上升到512并發(fā)連接的過程中,BWM和Envoy的延遲分布比Linkerd更穩(wěn)定。具體來說,Linkerd的平均延遲從58.42 ms至117.66 ms,增加101.40%,在相比之下,BWM和Envoy的平均延遲從約52 ms增加到約72 ms,增加38.46%。Linkerd的延遲變化很大,以512并發(fā)連接實驗為例,Linkerd的50%的請求在80.44 ms內(nèi),99%的所有請求在522.44 ms內(nèi),相比之下,BWM和Envoy的變化僅從約67 ms(50%)到大約145 ms(99%)。 表3 128并發(fā)連接下的測試結果 表4 256并發(fā)連接下的測試結果 表5 512并發(fā)連接下的測試結果 可以看出BWM和Envoy的性能表現(xiàn)明顯優(yōu)于Linkerd。最初,128并發(fā)連接下,三者性能差異很小,其中BWM的表現(xiàn)最為優(yōu)秀,BWM和Envoy的差距不大,但是兩者都明顯優(yōu)于Linkerd,Linkerd僅比其他兩個低約12%;256并發(fā)連接下,Linkerd、BWM和Envoy的QPS分別為3 005.75、4 559.11、4 583.77,512并發(fā)連接下,Linkerd、BWM和Envoy的QPS分別為5 085.25、7 015.28、7 146.75,差距隨著并發(fā)的增加而增加。需要注意的是,雖然BWM的性能和Envoy是非常相似的,但是最大響應時間(Max.RT)BWM均比Envoy小,考慮C++語言比Java存在的一定性能優(yōu)勢,因此BWM的性能表現(xiàn)十分優(yōu)秀。 4.3.2交互性能分析 為了評價本文設計的通信協(xié)議(BWMP)的有效性,本文在相同實驗條件下,分別測試使用HTTP協(xié)議通信和自定義協(xié)議通信下的性能表現(xiàn)。 實驗結果如表6所示,可見使用BWMP協(xié)議傳輸數(shù)據(jù)總量平均減少約9.26%,QPS平均增加約5.41%,說明BWMP協(xié)議對性能有一定的影響和提高。 表6 通信性能測試結果 4.3.3程序語言層面分析 眾所周知,編程語言的特性直接影響所實現(xiàn)系統(tǒng)的整體性能。本文原型系統(tǒng)和Linkerd都是基于Java實現(xiàn),而Envoy則基于C++實現(xiàn)。C++是基于靜態(tài)類型編譯的編程語言,在本質(zhì)上相比于Java更加高效。因此,從程序語言層面來看,Envoy的性能應該顯著優(yōu)于BWM和Linkerd,但實驗結果是BWM和Envoy的性能相近,顯著優(yōu)于采用同樣編程語言的Linkerd。因此考慮到編程語言本身對系統(tǒng)性能的影響,本文提出的服務網(wǎng)格性能優(yōu)化方法起到了很好的優(yōu)化效果。 服務網(wǎng)格是面向服務計算的新型基礎設施,為服務的靈活交互和全面的服務治理與服務監(jiān)控提供支撐。服務網(wǎng)格的性能優(yōu)化是提升系統(tǒng)并發(fā)處理能力的有效途徑。本文從計算模型和通信協(xié)議兩個方面提出了服務網(wǎng)格性能優(yōu)化的關鍵技術,設計了基于Reactor的高性能并發(fā)模型和輕量化的通信協(xié)議與高效的編解碼算法。通過實驗與當前主流的服務網(wǎng)格系統(tǒng)Linkerd和Envoy進行了性能對比,分別從并發(fā)性能和通信性能方面進行分析比較,實驗結果表明本文方法在響應時間和網(wǎng)絡傳輸數(shù)據(jù)量方面均起到了性能優(yōu)化作用。 目前本文的實驗只是基于簡單的模擬場景對提出方法的有效性進行了分析對比,后續(xù)工作將基于更多的真實應用更加深入和詳細地進行實驗和分析。此外,未來工作將從負載均衡和調(diào)度算法方面繼續(xù)深入研究服務網(wǎng)格的性能優(yōu)化技術,并將相關成果應用于主流的開源服務網(wǎng)格系統(tǒng),以進一步分析評估方法的有效性。3 系統(tǒng)設計
4 實 驗
4.1 實驗設計
4.2 評價指標
4.3 實驗結果分析
5 結 語