魏興雲(yún),任祥維,譚陸媛
(中國電子科技集團公司第三十研究所,四川 成都 610041)
隨著計算機與網(wǎng)絡(luò)技術(shù)的高速發(fā)展,在計算機上處理的工作越來越多,業(yè)務(wù)也越來越復(fù)雜,多個系統(tǒng)(節(jié)點)協(xié)同工作的需求也越來越大。為了高效地實現(xiàn)系統(tǒng)間數(shù)據(jù)共享、互操作,解決系統(tǒng)不易集成問題,對象管理組織(Object Management Group,OMG)在高級體系結(jié)構(gòu)(High Level Architecture,HLA)和通用對象請求代理體系(Common Object Request Broker Architecture,CORBA)等標準的基礎(chǔ)上,制定了采用以數(shù)據(jù)為中心發(fā)布-訂閱機制(Data Centric Publish Subscribe,DCPS)的分布式實時通信中間件技術(shù)規(guī)范:數(shù)據(jù)分發(fā)服務(wù)(Data Distribute Service,DDS)[1]。DDS基于主題進行數(shù)據(jù)發(fā)布-訂閱,適用于分布式節(jié)點之間的數(shù)據(jù)交換,其以數(shù)據(jù)為中心,能實現(xiàn)高效和實時地數(shù)據(jù)交換[2]。在工業(yè)自動化、分布式控制和仿真應(yīng)用等領(lǐng)域,許多實時應(yīng)用程序都構(gòu)建了以數(shù)據(jù)中心的DDS通信模型,其中部分應(yīng)用程序發(fā)布(提供或流式傳輸)數(shù)據(jù),供對該數(shù)據(jù)感興趣的遠程應(yīng)用程序訂閱使用。
根據(jù)規(guī)范,DDS主要分為如圖1所示的兩個層次,分別是DCPS層和本地數(shù)據(jù)重構(gòu)(Data Local Reconstruction Layer,DLRL)層。其中,DCPS是數(shù)據(jù)發(fā)布-訂閱系統(tǒng)的基本框架,其負責系統(tǒng)中數(shù)據(jù)的發(fā)布、訂閱、處理、分發(fā),并實現(xiàn)把主題數(shù)據(jù)發(fā)送給已訂閱的節(jié)點;DLRL層的目的是外部應(yīng)用程序與DDS內(nèi)部的數(shù)據(jù)交互,提供簡單的方式,使各個外部應(yīng)用能夠之間向DDS中獲取數(shù)據(jù)或者向DDS中寫入數(shù)據(jù)[1]。
本文所介紹的通信中間件主要參考DCPS層進行系統(tǒng)設(shè)計與實現(xiàn),因此下文主要對DCPS的發(fā)布-訂閱模型進行介紹。
DCPS是實現(xiàn)數(shù)據(jù)發(fā)布訂閱服務(wù)的基礎(chǔ)框架,其概念模型如圖2所示。它基于全局數(shù)據(jù)空間(Global Data Space,GDS)的概念,提供基于主題的數(shù)據(jù)發(fā)布和訂閱相關(guān)功能[1]。
DCPS包括主題、數(shù)據(jù)讀取器、訂閱者、數(shù)據(jù)寫入器、發(fā)布者等類型對象。以主題為中心,通過數(shù)據(jù)寫入器進行主題數(shù)據(jù)的寫入;通過數(shù)據(jù)讀取器進行主題數(shù)據(jù)的讀取;通過發(fā)布者和訂閱者進行主題數(shù)據(jù)的發(fā)布與訂閱。
按照屬性與職責范圍的不同可將DCPS分成基礎(chǔ)設(shè)施模塊、域模塊和數(shù)據(jù)發(fā)布訂閱模塊3個部分。基礎(chǔ)設(shè)施模塊定義了系統(tǒng)的交互方式、服務(wù)質(zhì)量(Quality of Service,QoS)以及質(zhì)量策略等公共基礎(chǔ)組件,是整個系統(tǒng)的基礎(chǔ)模塊。域模塊域和數(shù)據(jù)發(fā)布訂閱模塊均依賴域基礎(chǔ)設(shè)施模塊。域模塊作為系統(tǒng)服務(wù)的入口,系統(tǒng)通過該模塊創(chuàng)建主題、發(fā)布者、訂閱者。發(fā)布者和訂閱者只能在相同的域中進行主題數(shù)據(jù)的交互。數(shù)據(jù)發(fā)布訂閱模塊由主題、發(fā)布者、訂閱者、數(shù)據(jù)寫入器、數(shù)據(jù)讀取器等對象組成。發(fā)布者通過數(shù)據(jù)寫入器進行主題數(shù)據(jù)發(fā)布。訂閱者通過數(shù)據(jù)讀取器進行主題數(shù)據(jù)獲取。
DDS發(fā)布-訂閱系統(tǒng)分為集中式和分布式兩種體系結(jié)構(gòu)。
集中式發(fā)布-訂閱系統(tǒng)具有服務(wù)器節(jié)點和普通節(jié)點。其中服務(wù)器節(jié)點存儲了所有系統(tǒng)發(fā)布訂閱的數(shù)據(jù)信息,同時負責數(shù)據(jù)的調(diào)度、處理等各種事務(wù)。普通節(jié)點都連接到服務(wù)器節(jié)點,通過服務(wù)器節(jié)點進行數(shù)據(jù)的發(fā)布和訂閱,各個普通節(jié)點之間不直接相連[3]。集中式體系結(jié)構(gòu)的優(yōu)點是連接結(jié)構(gòu)簡單,系統(tǒng)易于協(xié)調(diào)和控制,但是整個系統(tǒng)的運行依賴于服務(wù)器節(jié)點,一旦服務(wù)器節(jié)點出現(xiàn)問題,整個系統(tǒng)都將癱瘓而無法工作。目前最具代表性的集中式發(fā)布-訂閱系統(tǒng)是TAO DDS,其為對象計算公司(Object Computing Inc.,OCI)的一個開源項目。
與集中式發(fā)布-訂閱不同,分布式發(fā)布-訂閱系統(tǒng)不存在服務(wù)器節(jié)點。該類型系統(tǒng)中每個節(jié)點都是相等的,都可根據(jù)需要成為主題數(shù)據(jù)的發(fā)布者和訂閱者,并且都維護著整個系統(tǒng)各個節(jié)點之間的發(fā)布-訂閱信息。該結(jié)構(gòu)中,數(shù)據(jù)的發(fā)布訂閱信息先在本節(jié)點處注冊,而后通過系統(tǒng)中的一個網(wǎng)絡(luò)中間件將本節(jié)點的信息發(fā)送至系統(tǒng)各節(jié)點處,使系統(tǒng)中所有節(jié)點處的發(fā)布-訂閱信息都相同。該系統(tǒng)中,各個節(jié)點兩兩之間均建立通信鏈路。節(jié)點發(fā)布數(shù)據(jù)的時候,直接通過節(jié)點之間的連接將數(shù)據(jù)發(fā)送給已訂閱數(shù)據(jù)的節(jié)點。相比于集中式結(jié)構(gòu),分布式結(jié)構(gòu)具有更高的可靠性。系統(tǒng)中部分節(jié)點出現(xiàn)問題,只影響與出現(xiàn)故障節(jié)點之間的數(shù)據(jù)交互,其他節(jié)點之間的數(shù)據(jù)發(fā)布訂閱仍可正常運行。同時,由于分布式結(jié)構(gòu)中兩兩節(jié)點之間均建立通信連接,鏈路數(shù)據(jù)比集中式結(jié)構(gòu)多,因此比較適合在小規(guī)模的網(wǎng)絡(luò)中進行使用。
ZeroMQ簡稱ZQM,是一種基于消息隊列的多線程網(wǎng)絡(luò)庫,能夠?qū)μ捉幼诸愋?、連接處理、幀等底層細節(jié)進行抽象,提供跨越多種傳輸協(xié)議的套接字。ZMQ采用無鎖的數(shù)據(jù)結(jié)構(gòu)來存儲消息,使用專門的后臺線程處理消息數(shù)據(jù),實現(xiàn)異步處理輸入/輸出(Input/Output,I/O)操作,因此具有良好的通信性能;ZMQ實現(xiàn)自動進行鏈路重連和消息緩存,對各個節(jié)點的啟動順序不作限制,而且可以自由地加入或者退出;ZMQ支持多種通信協(xié)議,包括傳輸控制協(xié)議(Transmission Control Protocol,TCP)、進程內(nèi)、進程間等;ZMQ提供了請求-應(yīng)答、發(fā)布-訂閱、管道等多種消息通信模式,通過對各種模式組合使用,有效降低分布式系統(tǒng)搭建的難度。
ZMQ提供了3種基本的通信模型,分別是請求-應(yīng)答、發(fā)布-訂閱和管道模式。
(1)請求-應(yīng)答模式。請求應(yīng)答模式通信模型如圖3所示??蛻舳耸褂肦EQ類型套接字,表示向服務(wù)端發(fā)起的請求;服務(wù)端使用REP類型套接字,表示對客戶端請求的響應(yīng)。這種模式下的通信過程是客戶端先向服務(wù)端發(fā)送數(shù)據(jù),服務(wù)端收到數(shù)據(jù)后向客戶端發(fā)送響應(yīng),客戶端收到響應(yīng)后方可發(fā)送下一次請求。該模式下,客戶端嚴格按照一發(fā)一收的模式進行通信,服務(wù)端則是嚴格按照一收一發(fā)的模式通信。這種模式對應(yīng)了經(jīng)典的客戶端/服務(wù)端(Client/Server,C/S)模型,可用在遠程過程調(diào)用(Remote Procedure Call,RPC)上[4]。
(2)發(fā)布-訂閱模式。在消息中間件,發(fā)布-訂閱是一種常見的模式。ZMQ中,消息發(fā)布者使用PUB類型的套接字,綁定到發(fā)布地址后即可進行消息發(fā)布。消息訂閱者使用SUB類型套接字,連接到發(fā)布者的發(fā)布地址后即可開始訂閱消息。消息發(fā)布者可以被多個消息訂閱者連接,訂閱者可以中途連接或者退出消息訂閱[4]。發(fā)布-訂閱模式的示意模型如圖4所示。
(3)管道模式。管道模式(Parallel Pipeline)是一種分布式并行處理模型,結(jié)構(gòu)如圖5所示。這個模型由3種類型的節(jié)點組成:第1個是任務(wù)分發(fā)者(Ventilator),其使用PUSH類型套接字,負責任務(wù)(Tasks)的分發(fā);第2個是任務(wù)處理/計算者(Worker),其使用 PULL和PUSH兩種類型套接字,首先使用PULL類型套接字從Ventilator中獲取任務(wù),其次對任務(wù)進行處理/計算,最后把結(jié)果(Result)通過PUSH類型套接字推送出去;第3個是結(jié)果收集器(Sink),通過使用PULL類型套接字,從多個Worker中獲取任務(wù)處理/計算結(jié)果。在管道模式中,一般有一個Ventilator節(jié)點、多個Worker節(jié)點和一個Sink節(jié)點,Ventilator會把任務(wù)平均PUSH到Worker。Sink節(jié)點也會公平地從Worker節(jié)點中獲取結(jié)果[4]。
主題發(fā)布-訂閱總線庫(Topic Publish Subscribe Bus Library,T-PSBLIB)參考DDS模型,構(gòu)建一個共享的全局數(shù)據(jù)空間,所有對該空間中的數(shù)據(jù)感興趣的應(yīng)用程序都可以加入。發(fā)布者加入數(shù)據(jù)空間后,通過總線庫提供的接口發(fā)布主題數(shù)據(jù),從而向數(shù)據(jù)空間提供信息;訂閱者加入數(shù)據(jù)空間后,通過總線提供的接口訂閱主題數(shù)據(jù)。每當發(fā)布者將新數(shù)據(jù)發(fā)送到這個全局數(shù)據(jù)空間,該總線庫就會把信息發(fā)送給已訂閱該主題的訂閱者[5]。TPSBLIB節(jié)點對數(shù)據(jù)的訪問示意如圖6所示。
TPSBLIB采用分布式體系結(jié)構(gòu),每個參與節(jié)點都是相等的,具備發(fā)布主題數(shù)據(jù)、訂閱主題數(shù)據(jù)和發(fā)現(xiàn)相同域中其他節(jié)點的能力。每個節(jié)點至少有一個域空間(Domain),域空間中有數(shù)據(jù)寫入器(Data Writer)、發(fā)布器(Publisher)、數(shù)據(jù)讀取器(DataReader)、訂閱器(Subscriber)和節(jié)點管理器(NodeManager)。數(shù)據(jù)寫入器和數(shù)據(jù)讀取器是應(yīng)用與中間件的交互實體,主要進行主題數(shù)據(jù)的寫入和讀取。下文對節(jié)點管理器、數(shù)據(jù)發(fā)布器和數(shù)據(jù)訂閱器的設(shè)計進行介紹。
TPSBLIB通信庫中,節(jié)點管理器的主要負責數(shù)據(jù)域中的節(jié)點發(fā)現(xiàn)信息更新與狀態(tài)同步,包括兩個部分的工作:一是定時廣播自身的狀態(tài)信息,這些信息包括節(jié)點名稱、本節(jié)點發(fā)布的主題數(shù)據(jù)信息、本節(jié)點訂閱的主題數(shù)據(jù)信息;二是接收處理其他節(jié)點廣播的狀態(tài)信息,并維護一個節(jié)點的狀態(tài)信息表,實現(xiàn)對數(shù)據(jù)域中各個節(jié)點的狀態(tài)管理,為節(jié)點對域中主題數(shù)據(jù)的發(fā)布訂閱提供信息支撐。
節(jié)點管理器通過組播的方式進行通信,同一域中各個節(jié)點的節(jié)點管理器加入相同的多播組,定時向該多播組發(fā)送節(jié)點自身的狀態(tài)信息,同時接收該多播組中的數(shù)據(jù),獲取其他節(jié)點廣播的節(jié)點狀態(tài)信息,并將收到的節(jié)點信息增加或者更新到節(jié)點信息表中[6]。節(jié)點管理器工作模式如圖7所示。
數(shù)據(jù)發(fā)布器的主要功能是根據(jù)給定的質(zhì)量策略建立相應(yīng)的數(shù)據(jù)發(fā)布鏈接。同時根據(jù)主題數(shù)據(jù)的質(zhì)量策略,把數(shù)據(jù)發(fā)送給已訂閱該主題數(shù)據(jù)的訂閱者。TPSBLIB中數(shù)據(jù)發(fā)布器主要由發(fā)送數(shù)據(jù)隊列、發(fā)布控制器和數(shù)據(jù)發(fā)布接口鏈路3個部分組成(見圖8)。
數(shù)據(jù)發(fā)布控制器是數(shù)據(jù)發(fā)布器的核心,管理和運行一個獨立的數(shù)據(jù)發(fā)布線程。該線程從發(fā)送數(shù)據(jù)隊列中獲取待發(fā)布的主題數(shù)據(jù),并將這些數(shù)據(jù)通過發(fā)布接口鏈路發(fā)送到已訂閱主題的訂閱者。
發(fā)布數(shù)據(jù)接口為數(shù)據(jù)寫入器或者其他模塊提供發(fā)布數(shù)據(jù)接口,對發(fā)送的數(shù)據(jù)按照特定的格式生成發(fā)送數(shù)據(jù)緩存,并把緩存相關(guān)信息寫入發(fā)送數(shù)據(jù)隊列。發(fā)送數(shù)據(jù)隊列使用優(yōu)先隊列,每個待發(fā)送的數(shù)據(jù)都有一個優(yōu)先級,發(fā)布控制器首先發(fā)布隊列中優(yōu)先級最高的數(shù)據(jù)。當發(fā)送數(shù)據(jù)隊列沒有數(shù)據(jù)的時候,發(fā)送控制器定時發(fā)布心跳消息,表明數(shù)據(jù)發(fā)布器在正常工作。
為了支持不同質(zhì)量屬性主題數(shù)據(jù)的發(fā)布訂閱,TPSBLIB中提供兩種策略的發(fā)布鏈路:可靠發(fā)布鏈路和非可靠發(fā)布鏈路??煽堪l(fā)布鏈路使用TCP協(xié)議,保證數(shù)據(jù)可靠的發(fā)送到訂閱者;非可靠鏈路使用用戶數(shù)據(jù)報協(xié)議(User Datagram Protocol,UDP)協(xié)議,占用的網(wǎng)絡(luò)帶寬比較少,但是不能保證所有訂閱者都收到完整的數(shù)據(jù)。
TPSBLIB中,數(shù)據(jù)發(fā)布接口鏈路采用ZMQ網(wǎng)絡(luò)庫的PUB類型套接字,相比于直接使用socket進行接口鏈路實現(xiàn),有效降低底層物理鏈路管理的復(fù)雜性。
TPSBLIB中,數(shù)據(jù)訂閱器由訂閱鏈路管理、數(shù)據(jù)接收處理、數(shù)據(jù)派遣處理、接收數(shù)據(jù)隊列和數(shù)據(jù)訂閱鏈路等部分組成,如圖9所示。
訂閱鏈路管理根據(jù)本節(jié)點訂閱的數(shù)據(jù)主題,自動與發(fā)布器建立通信鏈路,在數(shù)據(jù)發(fā)布器下線或者對應(yīng)的主題數(shù)據(jù)取消訂閱的時候,斷開與該發(fā)布器的連接鏈路。數(shù)據(jù)接收處理建立一個獨立的數(shù)據(jù)接收線程,等待并讀取訂閱鏈路中的數(shù)據(jù),并根據(jù)約定數(shù)據(jù)格式,對數(shù)據(jù)進行解析,恢復(fù)出完整的主題數(shù)據(jù)信息,并將這些主題數(shù)據(jù)寫入接收數(shù)據(jù)隊列。為了提高數(shù)據(jù)接收處理的穩(wěn)定性,數(shù)據(jù)派遣處理建立一個數(shù)據(jù)派遣線程。該線程從接收數(shù)據(jù)隊列中讀取數(shù)據(jù),并把數(shù)據(jù)發(fā)送給相應(yīng)的數(shù)據(jù)讀取器提供的主題數(shù)據(jù)處理者。
TPSBLIB中,數(shù)據(jù)訂閱鏈路使用ZMQ網(wǎng)絡(luò)庫的SUB類型套接字,與數(shù)據(jù)發(fā)發(fā)布鏈路的PUB類型套接字配合應(yīng)用,實現(xiàn)各個節(jié)點上下線的順序無關(guān)處理。
TPSBLIB的實現(xiàn)參考DDS的類結(jié)構(gòu),并根據(jù)上文設(shè)計對其進行調(diào)整簡化,類結(jié)構(gòu)體如圖10所示。圖10中DomainParticipant主要實現(xiàn)上文中的節(jié)點管理器功能,Publisher實現(xiàn)發(fā)布器的功能,Subscriber實現(xiàn)訂閱器功能[7]。
為便于應(yīng)用開發(fā),TPSBLIB提供配置文件對中間件相關(guān)信息進行配置,并通過提供簡單接口對中間件進行訪問控制,從而極大地提高應(yīng)用開發(fā)的便捷性和高效性。
配置文件采用XML格式。配置內(nèi)容包括節(jié)點信息配置、域信息配置、發(fā)布器與發(fā)布主題配置、訂閱器與訂閱主題配置等信息。配置文件格式如下所示。
應(yīng)用接口層為應(yīng)用提供簡單的接口,包括中間件初始化、設(shè)置主題數(shù)據(jù)接收回調(diào)、發(fā)送主題數(shù)據(jù)、關(guān)閉中間件4個,應(yīng)用接口函數(shù)聲明如下文。
void initSDDS(void);
typedef void recvSDDSTopicData(char* topic,char* source, char* data, int len);
void setSDDSTopicDataRecver(recvSDDSTopicDa ta* recv);
void sendSDDSTopicData(char* topic, char* data,int len);
void closeSDDS(void);
本文分析設(shè)計和實現(xiàn)了一個簡單數(shù)據(jù)發(fā)布訂閱通信庫(TPSBLIB),該通信庫參考DDS規(guī)范相關(guān)的概念與思路,并在ZeroMQ(ZMQ)網(wǎng)絡(luò)庫的基礎(chǔ)上進行實現(xiàn)。TPSBLIB采用數(shù)據(jù)發(fā)布訂閱通信模式,并提供數(shù)據(jù)可靠傳輸和非可靠傳輸兩種策略,基本滿足小規(guī)模分布式應(yīng)用系統(tǒng)對信息交換實時性和靈活性的需求。