本篇作為MD-SAL核心內(nèi)容的第三篇,我們將介紹RPC和Notification,并從進(jìn)程內(nèi)外的通信開(kāi)始,著重介紹遠(yuǎn)程過(guò)程調(diào)用和發(fā)布-訂閱機(jī)制,然后分析MD-SAL的通信交互過(guò)程。
圖片來(lái)自網(wǎng)絡(luò)
一、通信基礎(chǔ)
我們?cè)诰帉憜误w程序的代碼時(shí),通常關(guān)注的是類和類之間關(guān)系的設(shè)計(jì)、類內(nèi)的方法以及方法間的調(diào)用關(guān)系。在跨系統(tǒng)調(diào)用時(shí),我們通常需要關(guān)注系統(tǒng)調(diào)用的接口,并根據(jù)接口文檔進(jìn)行編程,此時(shí),涉及到跨系統(tǒng)、跨進(jìn)程的調(diào)用。有關(guān)進(jìn)程內(nèi)外的通信分類大致如下:
單體程序代碼通常是進(jìn)程內(nèi)通信,也就是本地過(guò)程調(diào)用,在同一CPU、同一內(nèi)存空間進(jìn)行。進(jìn)程間通信最原始的莫過(guò)于Socket通信,但寫起來(lái)相對(duì)于比較麻煩,人們希望能夠“簡(jiǎn)單地”編程,后來(lái)基于“如何實(shí)現(xiàn)分布式計(jì)算的編程?”這一課題,在論文《Implementing Remote Procedure Calls》中給出了方案,即“調(diào)用遠(yuǎn)程機(jī)器上的程序就像在本地機(jī)器的地址空間中一樣。隱藏分布式環(huán)境重要的部分:對(duì)參數(shù)和結(jié)果的編解碼、消息傳遞以及保留過(guò)程調(diào)用的語(yǔ)義”,提出了RPC的解決方案。
間接通信的本質(zhì)是“中介者”通信,是一種“間接”通信。它使得發(fā)送者和接收者不需要知道彼此的身份,并且不需要兩者同時(shí)在線,一方不在線的情況下也可以通信,實(shí)現(xiàn)了空間上和時(shí)間上的解耦。間接通信比較流行的技術(shù)有:
l發(fā)布-訂閱系統(tǒng):“中介者”;
l消息隊(duì)列系統(tǒng):發(fā)送者發(fā)送消息到隊(duì)列中,接收者從隊(duì)列中提取消息。
1.遠(yuǎn)程過(guò)程調(diào)用RPC
1.1基礎(chǔ)
RPC系統(tǒng)由User、User-stub、RPCRuntime、Server-stub和Server等5部分組成。其中,User、User-stub和RPCRuntime的實(shí)例在Caller machine上執(zhí)行;Server、Server-stub和RPCRuntime實(shí)例在Callee machine上執(zhí)行。簡(jiǎn)單調(diào)用的交互過(guò)程:
①User發(fā)起一個(gè)遠(yuǎn)程調(diào)用,則調(diào)用user-stub;
②user-stub負(fù)責(zé)封裝方法和參數(shù)放置,并放置到一個(gè)或多個(gè)包中,然后請(qǐng)求RPCRuntime;
③RPCRuntime將這些包可靠地傳輸給被調(diào)用者機(jī)器,同時(shí),調(diào)用進(jìn)程被掛起并等待結(jié)果包的返回;
④Server的RPCRuntime將包傳送給Server-stub;
⑤Server-stub解包,并本地調(diào)用會(huì)調(diào)用Server中相對(duì)應(yīng)的程序邏輯;
⑥Server的邏輯執(zhí)行完成,則將結(jié)果返回給Server-stub打包;
⑦Server-stub將結(jié)果傳給RPCRuntime;
⑧Server的RPCRuntime將包將被傳送回給User machine;
⑨User machine進(jìn)行解包,User得到返回結(jié)果。
1.2 RPC框架
2.發(fā)布-訂閱(publish-subscribe)
我們通過(guò)發(fā)布訂閱的一個(gè)開(kāi)源實(shí)現(xiàn)Kafka來(lái)講述發(fā)布-訂閱機(jī)制。Kafka是一種高吞吐量的分布式發(fā)布訂閱消息系統(tǒng)。如下圖所示,producer發(fā)布消息,consumer從消息隊(duì)列中獲取消息,broker用來(lái)接收發(fā)送的消息并將這些消息路由至隊(duì)列中。生產(chǎn)者將數(shù)據(jù)發(fā)布到他們選擇的主題。 生產(chǎn)者負(fù)責(zé)選擇分配給主題中哪個(gè)分區(qū)的記錄。
而消息是由Topic(主題)的形式組織起來(lái)的,一個(gè)Topic可以有0、1或多個(gè)consumer訂閱。對(duì)于每個(gè)Topic,又可分為多個(gè)Partition(分區(qū))。每個(gè)分區(qū)都是一個(gè)有序的,不可變的序列。 如下所示:
Partition中的每個(gè)記錄都分配了一個(gè)稱為偏移的順序ID號(hào),它唯一地標(biāo)識(shí)每個(gè)記錄。如下所示:
二、 MD-SAL ** RPC**
2.1.RPC定義
RPC采用YANG語(yǔ)言建模,使用“rpc”語(yǔ)句建模。我們以O(shè)penDaylight示例-Toaster為例介紹:rpc make-toast定義RPC操作的方法名、input用于定義RPC操作的輸入?yún)?shù)、output用于定義RPC操作的輸出參數(shù)。如下圖所示:
2.2.代碼編寫
1.生成代碼
YANG文件定義好之后,我們執(zhí)行命令:mvn clean install,可自動(dòng)生成:
l ToasterService:接口文件,定義與yang數(shù)據(jù)模型定義的RPC方法;
l MakeToastInput:提供make-toast調(diào)用的輸入?yún)?shù)。
l MakeToastInputBuilder:用于創(chuàng)建MakeToastInput實(shí)例的具體類。
2.實(shí)現(xiàn)接口
編寫OpenDaylightToaster實(shí)現(xiàn)ToasterService接口,添加makeToast函數(shù)代碼。
3. 注冊(cè)RPC服務(wù)
使用blueprint注冊(cè)RPC服務(wù)。
- 調(diào)用makeToast服務(wù)
我們可以使用POSTMAN測(cè)試工具,或者編寫應(yīng)用APP調(diào)用makeToast函數(shù),調(diào)用的請(qǐng)求為:
請(qǐng)求方法:POST
URL地址:http://localhost:8080/restconf/operations/toaster:make-toast
請(qǐng)求Body體:
2.3 小結(jié)
從RPC的定義和代碼編寫不難看出,RPC的定義通過(guò)YANG語(yǔ)言來(lái)建模,RPC的訪問(wèn)可以通過(guò)RESTCONF協(xié)議進(jìn)行,RPC的提供者通過(guò)blueprint來(lái)注冊(cè)RPC服務(wù)。
三、MD-SAL Notification
3.1.Notification定義
在支持NETCONF協(xié)議的網(wǎng)絡(luò)中,網(wǎng)絡(luò)設(shè)備使用Notification消息向網(wǎng)絡(luò)監(jiān)控發(fā)送通知事件以說(shuō)明網(wǎng)絡(luò)設(shè)備的某種狀態(tài)。OpenDaylight也采用了Notification消息通知,它被設(shè)計(jì)為一種發(fā)布/訂閱模式。同樣,我們以O(shè)penDaylight示例Toaster來(lái)說(shuō)明該機(jī)制。
在示例Toaster中,烤面包機(jī)不僅能烤面包,還能在沒(méi)有面包的情況下,發(fā)送一個(gè)toasterOutOfBread通知,告知消費(fèi)者現(xiàn)已無(wú)面包可烤。我們?cè)赮ANG文件中定義這個(gè)通知,如下圖所示:
3.2.代碼編寫
1.生成代碼
YANG文件定義好之后,我們執(zhí)行命令:mvn clean install,可自動(dòng)生成:
l ToasterOutOfBread:為toasterOutOfBread通知定義DTO接口。
l ToasterOutOfBreadBuild:用于創(chuàng)建ToasterOutOfBread實(shí)例的具體類。
l ToasterListener:實(shí)現(xiàn)烤面包機(jī)通知消費(fèi)者的接口,定義每種通知類型的接收方法。
2.生產(chǎn)者實(shí)現(xiàn)通知
3.生產(chǎn)者實(shí)現(xiàn)配置
OpenDaylightToaster需要訪問(wèn)MD-SAL的NotificationPublishService才能發(fā)送通知。 我們需要在blueprint文件中注入OpenDaylightToaster:
4.消息者實(shí)現(xiàn)
我們來(lái)看下如何從控制器中以編程方式訪問(wèn)ToasterService,實(shí)現(xiàn)消費(fèi)者KitchenService。示例中采用了“硬編碼”的方式。如下所示:
接下來(lái),我們修改KitchenServiceImpl以實(shí)現(xiàn)ToasterListener接口和通知方法。
KitchenServiceImpl需要在MD-SAL的NotificationPublishService中注冊(cè)才能接收通知。 我們需要配置blueprint文件:
這樣就可以O(shè)penDaylightToaster在發(fā)生OutOfBread事件時(shí)發(fā)送通知。
3.3 小結(jié)
Notification采用的是發(fā)布訂閱機(jī)制,本例中生產(chǎn)者為OpenDaylightToaster,消費(fèi)者為KitchenServiceImpl,中間代理為MD-SAL,具體為YANG和NotificationPublishService。如下圖所示:
ToasterService接口通過(guò)YANG模型構(gòu)建自動(dòng)生成,OpenDaylightToaster是該接口的一個(gè)具體實(shí)現(xiàn),通過(guò)blueprint實(shí)現(xiàn)關(guān)系的綁定。KitchenService理應(yīng)采用YANG模型構(gòu)建,但示例中采用的是硬編碼的形式,在KitchenServiceImpl中直接聲明ToasterService對(duì)象,如圖中的①和①ɑ所示。無(wú)論是生產(chǎn)者還是消費(fèi)者,都需要NotificationPublishService來(lái)進(jìn)行消息的發(fā)布和訂閱。
四、總結(jié)
文章寫到這里,就將YANG、DataStore、RPC和Notification這3個(gè)在MD-SAL中非常重要的點(diǎn)講述完了,在支持NETCONF協(xié)議配置的網(wǎng)絡(luò),還涉及到需要將網(wǎng)絡(luò)設(shè)備的Yang文件mount到控制器以實(shí)現(xiàn)基于NETCONF的控制。下一篇我們將MD-SAL的各個(gè)點(diǎn)串聯(lián)起來(lái),形成一條線。
-
通信
+關(guān)注
關(guān)注
18文章
6032瀏覽量
135993 -
RPC
+關(guān)注
關(guān)注
0文章
111瀏覽量
11536 -
sal
+關(guān)注
關(guān)注
0文章
2瀏覽量
2491
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論