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