田豐 王海 楊國勝 韋強



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