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