田豐 王海 楊國勝 韋強



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