蔡建坤
本文針對(duì)空管系統(tǒng)間信息交互的困難,研究分析ZeroMQ 的運(yùn)作原理、支持的工作模式,并描述了使用ZeroMQ 作為空管系統(tǒng)信息交換的通信模型,為空管應(yīng)用系統(tǒng)間信息交互提供基礎(chǔ)研究。
ZeroMQ 專(zhuān)為可擴(kuò)展的分布式或并發(fā)應(yīng)用程序而設(shè)計(jì),是一個(gè)高性能的異步消息庫(kù)[1]。按TCP/IP 協(xié)議,ZeroMQ 可作為新的網(wǎng)絡(luò)通信層,位于應(yīng)用層和傳輸層之間,是一個(gè)可以并行工作并在分布式系統(tǒng)之間傳播的可擴(kuò)展層。與消息中間件不同的地方,ZeroMQ 不需要啟動(dòng)任何專(zhuān)用的消息代理。ZeroMQ 可視為是一個(gè)套接字Socket 庫(kù),看起來(lái)像一個(gè)框架,使套接字編程更高效,更簡(jiǎn)單,更清晰。
當(dāng)使用ZeroMQ,數(shù)據(jù)流的操作如圖1 所示,通信中幾乎一切IO 操作都為異步的,主線程不會(huì)被阻塞。ZeroMQ 根據(jù)調(diào)用zmk_init 函數(shù)時(shí)傳輸?shù)男螀?chuàng)建相同數(shù)量的IO 線程。每個(gè)IO Thread 都有與之綁定的“ Poller”,依據(jù)操作系統(tǒng)的不同的平臺(tái),“Poller”應(yīng)用不同的網(wǎng)絡(luò)IO 模型(Kequeue、Select、Epoll 、Poll、Devpoll 等)。主 線 程和IO 線程通過(guò)郵箱(Mail Box)進(jìn)行通信。當(dāng)服務(wù)器開(kāi)始聽(tīng)或客戶端發(fā)起連接時(shí)它會(huì)創(chuàng)建zmk_connecter 或zmk_listener 在主要線程,通過(guò)郵箱(Mail Box)與IO 線程連接,以及IO 線程增加zmk_connecter 或zmk_listener 用于聽(tīng)讀/寫(xiě)事件。當(dāng)服務(wù)器首次與客戶端通信時(shí),它會(huì)創(chuàng)建zmk_init 以發(fā)送身份驗(yàn)證。檢查完成后,雙方將為此連接創(chuàng)建會(huì)話,然后雙方將通過(guò)會(huì)話進(jìn)行通信。每個(gè)會(huì)話都連接到管道,主線程僅通過(guò)從管道讀取/寫(xiě)入數(shù)據(jù)來(lái)發(fā)送和接收消息。會(huì)話實(shí)際上并不與內(nèi)核共享IO 數(shù)據(jù),相反,IO 數(shù)據(jù)在會(huì)話中通過(guò)“plugin”到“Session”中的“Engine”與內(nèi)核交換。
圖1 ZeroMQ內(nèi)部數(shù)據(jù)架構(gòu)圖
ZeroMQ 提供四種通信協(xié)議,格式為ipc://,inproc://,tcp://,pgm://,分別對(duì)應(yīng)進(jìn)程間,進(jìn)程內(nèi),機(jī)器間和廣播。通信協(xié)議非常易于配置,通過(guò)類(lèi)似于URL 的字符串指定,ZeroMQ 自動(dòng)解釋協(xié)議,地址,端口號(hào)和其他信息[1]。
ZeroMQ 將消息通信分成推拉模型、一對(duì)一結(jié)對(duì)模型、發(fā)布訂閱模型、請(qǐng)求回應(yīng)模型4 種模型。這四個(gè)模型基本滿足了空管系統(tǒng)的網(wǎng)絡(luò)通信模型,在實(shí)踐中,您可以組合兩個(gè)或更多模型進(jìn)行使用。
1)一對(duì)一結(jié)對(duì)模型。消息一對(duì)一通信模型的最簡(jiǎn)單通信模型,可以被視為T(mén)CP 連接,但TCP 服務(wù)器只能接受一個(gè)連接。與請(qǐng)求回應(yīng)模型不同,數(shù)據(jù)可以在兩個(gè)方向上運(yùn)行。
2)請(qǐng)求回應(yīng)模型。請(qǐng)求端提出請(qǐng)求,等待回應(yīng)端答復(fù),請(qǐng)求與回應(yīng)對(duì)應(yīng)。對(duì)應(yīng)請(qǐng)求端來(lái)說(shuō),它是一個(gè)發(fā)—收配對(duì),對(duì)于回應(yīng)端來(lái)說(shuō),它是一個(gè)收—發(fā)配對(duì)。相對(duì)于與一對(duì)一結(jié)對(duì)模型,其區(qū)別在于可以是N 個(gè)(N 大于等于1)的請(qǐng)求。這個(gè)模型主要用于任務(wù)分配和遠(yuǎn)程調(diào)用[2]。
3)發(fā)布訂閱模式。發(fā)布者單向傳播數(shù)據(jù),不管數(shù)據(jù)是否被客戶訂閱到。如果發(fā)布者在開(kāi)始輸出時(shí)沒(méi)有連接,發(fā)布者將立即丟棄信息。沒(méi)有連接和信息的丟失問(wèn)題可以通過(guò)在組合請(qǐng)求響應(yīng)模型來(lái)解決。訂閱者只負(fù)責(zé)接收,但不負(fù)責(zé)提供反饋。如果訂閱速度快或與發(fā)布者相同,數(shù)據(jù)可以及時(shí)使用,如果處理速度慢,數(shù)據(jù)會(huì)堆積到訂閱者身上。該模型主要用于數(shù)據(jù)分發(fā)[3]。
4)推拉模式。服務(wù)器用作推送端,客戶使用作為拉取端,如果多個(gè)客戶端同時(shí)連接到服務(wù)器,該服務(wù)將在內(nèi)部執(zhí)行負(fù)載平衡發(fā)布到客戶端上。與發(fā)布訂閱者模型相比,此模型不丟棄信息,如消費(fèi)者能力不足,模型為消費(fèi)者提供了并行處理選項(xiàng)[3]。該模型用于平行多任務(wù)處理場(chǎng)景。
ZeroMQ 具有以下特征:
1)異步,支持高并發(fā),比TCP 更快,適用于大型集群和分布式計(jì)算;
2)提供異步I/O 模式,支持超過(guò) 30 種的編程語(yǔ)言,包括所有主流編程語(yǔ)言;
3)提供多種消息傳遞機(jī)制和內(nèi)置豐富的組合模式可用于簡(jiǎn)化大型分步式計(jì)算架構(gòu);
4)良好的跨平臺(tái)性,支持多種操作系統(tǒng);
5)擁有iMatik 在商業(yè)層面的支持,它是完全免費(fèi)的,且開(kāi)發(fā)者社區(qū)活躍,發(fā)展迅速。
本文介紹的四種ZeroMQ 模型總結(jié)了空管系統(tǒng)網(wǎng)絡(luò)通信的通用模型,在實(shí)踐中,可根據(jù)空管系統(tǒng)應(yīng)用需求組合兩種或更多模型來(lái)構(gòu)建解決方案。如代理模式,此模式主要用于按需擴(kuò)展請(qǐng)求響應(yīng)模式。如果需要擴(kuò)展多響應(yīng)服務(wù)器,可以使用代理模式。ROUTER 對(duì)應(yīng)于一個(gè)請(qǐng)求,它等同于響應(yīng)服務(wù)器,它執(zhí)行先收后發(fā),接收和發(fā)送循環(huán)。當(dāng)它在內(nèi)部從前端接收請(qǐng)求,然后發(fā)送DEALER 請(qǐng)求,該請(qǐng)求接收ROUTER 消息并將消息發(fā)送給響應(yīng)者,但DEALER 面臨N 個(gè)響應(yīng)者。通過(guò)代理模式的轉(zhuǎn)變,請(qǐng)求響應(yīng)模式將自動(dòng)擴(kuò)展容量。如果將此機(jī)制集成到操作中,則代理模式是異步的。與異步的接線員類(lèi)似,將N個(gè)請(qǐng)求與M 個(gè)響應(yīng)連接起來(lái)。并確保它們是平衡的。
因此,可以說(shuō)ZeroMQ 幾乎可以滿足現(xiàn)有的通信要求,無(wú)論是單機(jī)還是分布式。
以下通過(guò)模擬客戶端和服務(wù)端的通信,說(shuō)明采用ZeroMQ 進(jìn)行系統(tǒng)間信息交換時(shí)的通信模型。
采用ZeroMQ 進(jìn)行空管系統(tǒng)通信時(shí),客戶端或服務(wù)端的程序都設(shè)計(jì)為由主線程和IO 線程組成。主線程主要負(fù)責(zé)創(chuàng)建或銷(xiāo)毀IO 線程通信的上下文和作為消息的生產(chǎn)者或消費(fèi)者;IO 線程則負(fù)責(zé)利用ZeroMQ 進(jìn)行通信。下面各自對(duì)客戶端和服務(wù)端的主線程和IO 線程的工作流程進(jìn)行說(shuō)明。
采用ZeroMQ 通信時(shí),客戶端或服務(wù)器程序設(shè)計(jì)為由主線程和IO 線程組成。主線程主要負(fù)責(zé)創(chuàng)建或銷(xiāo)毀IO 通信的上下文,既不是制造消息也不是消息的消費(fèi)者,IO 線程負(fù)責(zé)與ZeroMQ 通信。下面是主線程和和IO 線程的工作流程。
2.5.1 客戶端的主線程的工作流程
1)調(diào)用zmq_init 創(chuàng)建context 指針;
2)創(chuàng)建IO 線程對(duì)象;
3)創(chuàng)建mail box;
4)啟動(dòng)IO 線程;
5)調(diào)用zmq_socket 根據(jù)指定模式創(chuàng)建socket指針;
6)調(diào)用zmq_connect 根據(jù)指定通信方式連接服務(wù)端;
7)創(chuàng)建session_t 指針;
8)添加會(huì)話指針到IO 線程;
9)創(chuàng)建zmq_connector_t 指針;
10)連接到connector,由IO 現(xiàn)場(chǎng)與服務(wù)端建立連接;
11)調(diào)用zmq_send 將消息寫(xiě)入與會(huì)話相關(guān)聯(lián)的通道;
12)調(diào)用zmq_close 關(guān)閉套接字;
13)調(diào)用zmq_term 銷(xiāo)毀上下文。
2.5.2 客戶端的IO 線程的工作流程
1)IO 線程調(diào)用start_connting 函數(shù)連接服務(wù)端;
2)在連接成功后,發(fā)送peer_identity;
3)通過(guò)會(huì)話讀取管道中的消息;
4)通過(guò)engine 向服務(wù)器發(fā)送消息。
2.5.3 服務(wù)端主線程的工作流程
1)調(diào)用zmq_init 創(chuàng)建context 指針;
2)創(chuàng)建IO 線程對(duì)象;
3)創(chuàng)建mail box;
4)啟動(dòng)IO 線程;
5)調(diào)用zmq_socket 根據(jù)指定的模式創(chuàng)建socket 指針;
6)調(diào)用zmq_bind 根據(jù)指定的通信方式監(jiān)聽(tīng)客戶端的連接請(qǐng)求;
7)創(chuàng)建監(jiān)聽(tīng)者指針;
8)Attach 到監(jiān)聽(tīng)者;
9)調(diào)用zmq_recv 從session 關(guān)聯(lián)管道讀取消息;
10)通信結(jié)束時(shí),調(diào)用zmq_close 關(guān)閉socket;
11)調(diào)用zmq_term 銷(xiāo)毀context。
2.5.4 服務(wù)端IO 線程的工作流程
1)接受客戶端連接請(qǐng)求,創(chuàng)建zmq_init_t 指針;
2)創(chuàng)建sesstion_t 指針;
3)通過(guò)engine 從客戶端接收消息;
4)通過(guò)sesstion 將消息寫(xiě)入管道。
ZeroMQ 使用組合多模式在空管系統(tǒng)網(wǎng)絡(luò)中完成通信任務(wù)和擴(kuò)展任務(wù),同時(shí),它隱藏了復(fù)雜的網(wǎng)絡(luò)編程細(xì)節(jié),如協(xié)議橋接、重連、補(bǔ)發(fā)等等。除了為不同的操作系統(tǒng)提供完整的編程接口外,還可以減少移植問(wèn)題。本文通過(guò)研究ZeroMQ 的運(yùn)作原理、支持的工作模式,描述了使用ZeroMQ 作為空管系統(tǒng)信息交換的通信模型,為空管應(yīng)用系統(tǒng)間信息交互提供基礎(chǔ)研究成果。