田豐 王海 楊國(guó)勝 韋強(qiáng)
摘要:為了應(yīng)對(duì)民航業(yè)務(wù)擴(kuò)展、業(yè)務(wù)復(fù)雜度增加的趨勢(shì),分析了當(dāng)前常見的多線程通訊方式,提出一種基于共享內(nèi)存的多進(jìn)程純異步通信方法。建立快速、可靠、可擴(kuò)展、可獨(dú)立部署并完全托管的消息隊(duì)列服務(wù),在保障傳輸可靠性、數(shù)據(jù)一致性的情況下,降低子系統(tǒng)間的耦合度,實(shí)現(xiàn)系統(tǒng)間的高效通信。通過(guò)部署少量進(jìn)程就可以提供系統(tǒng)的吞吐量,降低交易響應(yīng)時(shí)間。
關(guān)鍵詞:多進(jìn)程;異步;并發(fā);通訊
中圖分類號(hào):TP319? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2021)27-0064-04
1 背景
隨著民航業(yè)務(wù)板塊的擴(kuò)張、業(yè)務(wù)服務(wù)的增加、互聯(lián)網(wǎng)技術(shù)的發(fā)展,企業(yè)系統(tǒng)平臺(tái)逐步根據(jù)服務(wù)內(nèi)容由集中的單體系統(tǒng)拆分成多個(gè)子業(yè)務(wù)系統(tǒng)。相較于集中式單體系統(tǒng)中模塊間的數(shù)據(jù)交互,子業(yè)務(wù)系統(tǒng)間交互更為復(fù)雜, 在業(yè)務(wù)處理過(guò)程中,往往需要各業(yè)務(wù)系統(tǒng)之間分工合作,訪問(wèn)各子系統(tǒng)對(duì)外開放接口獲取信息[1]。因此,對(duì)系統(tǒng)數(shù)據(jù)傳輸?shù)耐掏铝考翱煽啃砸灿辛烁叩囊蟆?/p>
2 多進(jìn)程通訊現(xiàn)狀
大部分的業(yè)務(wù)系統(tǒng)為保障數(shù)據(jù)的一致性,滿足各業(yè)務(wù)系統(tǒng)間合作的需求,子系統(tǒng)間通常通過(guò)RPC同步調(diào)用服務(wù),但在某些場(chǎng)景中,RPC同步調(diào)用的響應(yīng)時(shí)間較長(zhǎng),造成資源的浪費(fèi),系統(tǒng)吞吐量下降。以AV航信查詢系統(tǒng)為例:當(dāng)用戶要查詢北京到洛杉磯的航班時(shí),AV系統(tǒng)需要同時(shí)訪問(wèn)Delta、Southwest航空公司的航班信息,整合后返回給調(diào)用方。如圖所示:
假設(shè)業(yè)務(wù)處理時(shí)間為0秒,Delta響應(yīng)時(shí)間為2秒,Southwest響應(yīng)為3秒。那么,一個(gè)請(qǐng)求的響應(yīng)時(shí)間為5秒。我們系統(tǒng)的最大并發(fā)量為3個(gè)請(qǐng)求,那么當(dāng)并發(fā)請(qǐng)求數(shù)大于3時(shí),剩余的請(qǐng)求只能堆積在消息隊(duì)列中。其次,3個(gè)進(jìn)程需要花費(fèi)5秒的時(shí)間在等待應(yīng)答,并且不做任何其他事情。這將導(dǎo)致系統(tǒng)的吞吐量遇到瓶頸,且系統(tǒng)的CPU、內(nèi)存使用率低。由此可見,RPC服務(wù)調(diào)用雖然能夠滿足實(shí)時(shí)調(diào)用的業(yè)務(wù)場(chǎng)景,但針對(duì)上述異步、業(yè)務(wù)操作復(fù)雜的場(chǎng)景,業(yè)務(wù)系統(tǒng)的性能目標(biāo)無(wú)法滿足。
為了提高吞吐量、降低響應(yīng)時(shí)延,現(xiàn)有技術(shù)提出了通過(guò)增加進(jìn)程個(gè)數(shù)來(lái)提高吞吐量的半同步通訊方式。該方式是在上述方案的基礎(chǔ)上進(jìn)行的改進(jìn),將兩次同步調(diào)用變?yōu)楫惒秸{(diào)用[2]??梢酝瑫r(shí)發(fā)送兩個(gè)請(qǐng)求,再獲取應(yīng)答。
如上圖所示,這種方案的處理時(shí)間取決于外部系統(tǒng)的最大響應(yīng)時(shí)間,即3秒。
然而,這種優(yōu)化方案依然存在問(wèn)題。首先,這種方案無(wú)法提前預(yù)估并發(fā)量。高峰期時(shí)并發(fā)量大,而低峰期時(shí)并發(fā)量很少。而在低峰期部署大量的處理進(jìn)程反而會(huì)導(dǎo)致資源的浪費(fèi)[3]?!安渴鸲嗌龠M(jìn)程合適?”的問(wèn)題依然沒(méi)有得到解決[4]。其次,進(jìn)程在等待應(yīng)答的3秒過(guò)程依然無(wú)法處理其他請(qǐng)求,意味著其他請(qǐng)求依然需要排隊(duì)。
3 多進(jìn)程異步并發(fā)通訊設(shè)計(jì)
針對(duì)上述現(xiàn)有技術(shù)的問(wèn)題,本文提出一種基于共享內(nèi)存的多進(jìn)程純異步通信方法,抽取進(jìn)程狀態(tài)并存儲(chǔ)于在傳輸過(guò)程中動(dòng)態(tài)創(chuàng)建的共享內(nèi)存組件存儲(chǔ)中,釋放無(wú)狀態(tài)進(jìn)程的等待時(shí)間,建立快速、可靠、可擴(kuò)展、可獨(dú)立部署并完全托管的消息隊(duì)列服務(wù),在保障傳輸可靠性、數(shù)據(jù)一致性的情況下,降低子系統(tǒng)間的耦合度,實(shí)現(xiàn)系統(tǒng)間的高效通信。一方面部署少量進(jìn)程即可以增加吞吐量,另一方面在等待異步應(yīng)答的過(guò)程中依然可以響應(yīng)其他交易請(qǐng)求。
3.1 系統(tǒng)組成
面向多進(jìn)程的純異步通信裝置由服務(wù)消費(fèi)方、異步消息交互服務(wù)和服務(wù)提供方組成。其中異步消息交互服務(wù)分為4個(gè)組件,分別是數(shù)據(jù)接入服務(wù)組件、消息隊(duì)列組件、異步通信進(jìn)程池和共享內(nèi)存組件。
數(shù)據(jù)接入服務(wù)組件:負(fù)責(zé)接受服務(wù)消費(fèi)方各種形式的并發(fā)連接請(qǐng)求,并將請(qǐng)求放到對(duì)應(yīng)的消息隊(duì)列中。
消息隊(duì)列組件:面向流量峰值的處理方案,當(dāng)消息涌入時(shí),首先將請(qǐng)求或異步應(yīng)答存放入消息隊(duì)列中,再根據(jù)流量控制策略進(jìn)行后續(xù)處理。
異步通信進(jìn)程池:每個(gè)進(jìn)程有一個(gè)I/O線程,負(fù)責(zé)與服務(wù)提供方進(jìn)行直接通信,根據(jù)消息中的參數(shù)信息,與對(duì)應(yīng)的主服務(wù)端或從服務(wù)端建立連接、異步發(fā)送相關(guān)消息,接收服務(wù)提供方的應(yīng)答結(jié)果,并存放至消息隊(duì)列中。
共享內(nèi)存組件:共享內(nèi)存組件在數(shù)據(jù)交互的過(guò)程中動(dòng)態(tài)創(chuàng)建異步交互上下文,根據(jù)業(yè)務(wù)特征存儲(chǔ)某組數(shù)據(jù)交互的上下文,及中間結(jié)果。
3.2 實(shí)現(xiàn)原理
面向多進(jìn)程的純異步通信方法在整個(gè)交易過(guò)程中采用完全異步的方式,沒(méi)有任何阻塞點(diǎn)。在進(jìn)程發(fā)起異步請(qǐng)求后,進(jìn)程并不等待,而是繼續(xù)處理其他請(qǐng)求;當(dāng)異步應(yīng)答回來(lái)后,再通過(guò)讀取上下文,恢復(fù)現(xiàn)場(chǎng),繼續(xù)處理上次交易。
具體進(jìn)程處理過(guò)程如下圖所示:
步驟1. http接入收到請(qǐng)求后將請(qǐng)求放入消息隊(duì)列
步驟2. 進(jìn)程讀取消息隊(duì)列后,
1)如當(dāng)前消息屬性為請(qǐng)求,則生成全局交易號(hào),保存原始請(qǐng)求報(bào)文,應(yīng)用需要暫存的kv數(shù)據(jù),以及要等待的異步應(yīng)答個(gè)數(shù)等上下文數(shù)據(jù),發(fā)起異步調(diào)用,轉(zhuǎn)步驟2。
2)如當(dāng)前消息屬性為應(yīng)答,讀取上下文。
①如果應(yīng)答未全部接收完畢,則保存上下文,轉(zhuǎn)步驟2
②如果應(yīng)答全部接收完畢,則刪除上下文,轉(zhuǎn)步驟3
步驟3.依據(jù)原始請(qǐng)求,及收到的全部異步應(yīng)答,整合數(shù)據(jù),返回消費(fèi)者。
注:異步應(yīng)答回來(lái)后,異步通訊線程會(huì)將異步應(yīng)答放入消息隊(duì)列。
4 共享內(nèi)存
實(shí)施方案的關(guān)鍵問(wèn)題在于共享內(nèi)存結(jié)構(gòu)如何快速定位,在此選擇了hash+鏈表的方式。此外,由于應(yīng)用保存上下文的數(shù)據(jù)長(zhǎng)度的不確定性,需要實(shí)現(xiàn)基于共享內(nèi)存的slab內(nèi)存分配算法。
4.1 創(chuàng)建共享內(nèi)存
進(jìn)程間通訊采用SysV SHM共享內(nèi)存/SEM信號(hào)機(jī)制[5]。其共享內(nèi)存結(jié)構(gòu)如圖6所示。
1)AsynCtl:記錄整個(gè)共享內(nèi)存大小及hash桶偏移量