ipcz 是chromium的跨進程通信系統。z可能是代表zero,表示0拷貝通信。
chromium的文檔是非常豐富的,關于ipcz最重要的一篇官方文檔是IPCZ。
關于ipcz本篇文章主要的目的是通過源代碼去分析它的實現。再進入分析前我們先對官方文檔做一個總結,來說明ipcz的能力。 ipcz和一般的ipc系統不同主要有點個方面
- 0拷貝通信
- 消除代理能力
0拷貝通信比較簡單,消除代理能力是什么意思呢?
考慮這樣一個場景, 有a,b,c三個進程通信,a和b之間存在鏈接,b和c之間存在連接,那么a要和c通信,只能通過b進行代理。這顯然造成了一定性能損失和資源浪費。 在ipcz系統中,如果b發現自己是代理節點,可以幫助a和c直接建立鏈接來消除代理。
顯然ipcz的設計初衷就是要建立一個類似ip協議的路由網絡能力。
ipcz的整體結構圖如下:
一般進程里面有一個Node節點, 用NodeLink記錄兩個Node的連接(用于找到對端)。 使用Driver Transport 表示一個傳輸點,也就是維護Node 之間的通信通道(一般是socket鏈接)。 兩個Node內可以有多個子鏈接,每個子鏈接的端點為Portal, 每個Portal 又對應一個Router, Router的主要作用是對消息進行接收或者轉發。兩個Router之間的鏈接用RouterLink表示。 兩個Node 之間通信的消息內容都放在一塊共享內存上, Driver Transport 只負責傳遞控制信息,這樣來實現0拷貝。
整個進程通信系統中一般有一個Node為Broker節點,在代理消除過程中,為了幫助a和c建立通信鏈接的,需要第三者來協調,這個第三者需要a和c都能和它通信,在ipcz系統中這樣的節點叫Broker Node。Broker Node 是有名節點,其他進程可以通過名字來和它建立通信(一般為有名socket管道)。
一般一個ipcz系統中每個進程對應一個Node,整個系統只有一個Broker Node。
有了對數據結構的基本認識,我們來介紹代理消除。
這里ac通信需要b進行代理,可以通過命令來消除代理:
- B告訴A自己是中間人,并告知C將向A發送直連請求
- B告訴C自己是中間人
- 如果AC沒有NodeLink 需要連接Brokers協助a和c之間創建NodeLink(通信管道)
- c借助AC之間的NodeLink創建一個ACx的RouterLink
- C向A發送直連請求, 使用ACx bypass AB1
- 節點A根據節點B提供的信息對該請求進行驗證,即該請求來自預期的節點C,并且涉及AB1。然后,節點A通過相應地更新其路由器的鏈接來滿足該請求。
- 后續A和C的通信都通過ACx進行。
注意,AB1和BC5仍然保留著。它們現在被稱為衰減鏈接(decaying links),并將會隨著時間的推移逐漸淘汰。
上述代理消除是簡單的只有一個代理節點的消除,在存在多個代理節點的情況可能混造成混亂
比如這個例子,D和E通信,A、B、C都是代理節點。 如果A,B,C 同時發現自己是代理節點,請求代理消除,那么會造成混亂,如何解決這個問題?
IPCZ 引入了中心鏈接和邊緣鏈接的概念,每條路徑的生命周期始于兩個路由器之間的單個鏈接。該鏈接被指定為路徑的中央鏈接,每條路徑都只有一個中央鏈接。其他鏈接為邊緣鏈接,代理選擇繞過的規則很簡單:只有在代理路由器與中心鏈接相鄰時,才能繞過代理。 消除代理建立新的連接之后的連接成為新的中心鏈接。
有個中心鏈接的概念可以進一步說明代理消除的過程。首先要知道在ipcz中存在向內和向外方向的概念。假如某個消息由某router發出,該消息向中心鏈接方向移動,則這個消息的方向為向外。 某個消息由某個router 發出,這個消息遠離中心鏈接,則這個消息的方向為向內。
舉例如上圖:
AB1是中心鏈接,B router向 A router發送消息為向外方向,通向A向B發送消息為向內方向。
AE0是邊緣鏈接,E router 向A發送消息為向外方向,A router 向E router發送消息為向內方向。
BC5也是邊緣鏈接,B router向C router發送消息為向內方向,C router 向B router 發送消息為向外方向。
同樣,路由器B被認為是路由器A的向外對等方,路由器E被認為是路由器A的向內對等方。路由器A是路由器E的向外對等方,路由器E沒有向內對等方,因為它是終端路由器。
在啟動代理繞過的過程中,代理路由會先通知其向外對等要進行代理消除, 再通知其向內對等提發起代理消除,直接請求broker 建立新的鏈接。
舉例要消除E->A->B 中A代理:
- A告訴B自己是中間人,并告知E將向B發送直連請求
- A告訴E自己是中間人
- 如果EB沒有NodeLink 需要連接Brokers協助E和B之間創建NodeLink(通信管道)
- E借助EB之間的NodeLink創建一個EBx的RouterLink
- E向B發送直連請求, 使用EBx bypass AB1 和 AE0
- 節點B根據節點A提供的信息對該請求進行驗證,即該請求來自預期的節點E,并且涉及AB
- 然后,節點B通過相應地更新其路由器的鏈接來滿足該請求。
- 后續E和B的通信都通過EBx進行。
本篇文章就到這里,下一篇文章通過代碼分析。