RPC

進程間通信(IPC)是在多任務操作系統或聯網的計算機之間運行的程序和進程所采用的通信技術,IPC有兩種類型的進程間通信的方式分別是本地過程調用(LPC)和遠程過程調用(RPC)。

本地過程調用LPC

本地過程調用(LPC)用于多任務操作系統中,使同時運行的任務能夠相互會話,任務共享內存空間以實現任務同步和互相發送消息。

例如:完成一個本地函數的調用

int add(int x, int y){
  return x + y;
}
int a = 1;
int b = 2;
int result = add(a, b);

add()函數的執行流程

  1. 分別將變量a和b的值壓入棧
  2. 執行add()函數,從棧中取出a和b的值,賦值給x和y。
  3. 計算x加y的值并保存到棧中
  4. 退出add()函數將x加y的值賦值給result

本地過程調用發生在同一進程中,共享內存區域。而RPC通信則需要跨域不同機器、不同進程,因此需要解決三個問題:函數ID(服務尋址)、數據流的序列化和反序列化、網絡傳輸

如果add()函數調用在客戶端,執行函數的函數體卻在遠程機器上,如何告知機器如何調用這個方法呢?

首先客戶端需要告訴服務器,需要調用的函數,這里函數和進程ID存在一個映射,客戶端遠程調用時需要檢查一下函數以找到對應的ID,然后執行函數的代碼。

客戶端需要將本地參數傳遞給遠程函數,本地調用的過程中直接壓棧即可。但在遠程調用過程中不在同一個內存中,無法直接傳遞參數的參數,因此需要客戶端將參數轉換為字節流,傳遞給服務器。服務器再將字節流轉換為自身能讀取的格式,這是一個序列化和反序列化的過程。

當數據準備好之后,如何進行傳輸呢?網絡傳輸層需要將調用的ID和序列化后的參數傳遞給服務器,然后將計算好的結果序列化傳遞給客戶端。因此TCP層可以完成上述操作。那么為什么不使用HTTP層呢?由于HTTP在應用層中完成,整個通信的代價比較高,RPC直接基于TCP進行遠程調用,數據傳輸在傳輸層TCP完成,更加適合對效率要求比較高的場景。RPC主要依賴于客戶端和服務器之間建立的Socket鏈接進行,但底層實現比REST更為復雜。

遠程過程調用RPC

遠程過程調用(RPC)類似于LPC,只是在網絡中工作,RPC開始是出現在SUN微系統公司和HP公司運行的UNIX操作系統中。

RPC的概念與技術早在1981年由Neison提出,1984年Birrel和Neison將其用于支持異構型分布式系統的通訊。Birrell的RPC模型引入存根進程(stub)作為遠程的本地代理,調用RPC運行時庫來傳遞網絡中的調用。Stub和RPC runtime屏蔽了網路所涉及的細節。特別是參數編碼與轉碼以及網絡任務的多樣性。RPC作為網絡通訊與委托計算的實現機制,在方法、協議、語義和實現上不斷發展,種類繁多,其中SUN公司和開發軟件基金會在分布式產品中所建立和使用的RPC較為典型。

RPC(Romote Procedure Call)遠程過程調用,RPC是通信協議,該協議允許運行于一臺計算機的程序調用另一臺計算機的子程序,開發人員無需額外為交互作用編程。若軟件采用面向對象編程,那么RPC又稱為遠程調用或遠程方法調用。簡單來說,遠程調用協議是一種通過網絡從遠程計算機程序上請求服務,同時無需了解底層網絡技術的協議。

RPC是一種用于構建基于客戶端/服務器(C/S)的分布式應用程序技術,調用者與被調用者可能在同一臺服務器上,也可能在由網絡連接的不同服務器上。對客戶端和服務器而言,使用RPC時網絡通信是透明的,遠程調用如何本地調用一樣簡單。簡單來說,RPC就是要像調用本地函數一樣去調用遠程函數。

RPC

RPC解決了什么問題?

  1. 解決分布式系統中,服務之間的調用問題。
  2. 遠程調用時,能夠像本地調用一樣方便,讓調用者感知不到遠程調用的邏輯。

為什么需要RPC?

  1. RPC可以用HTTP協議實現,HTTP是建立在TCP之上最廣泛使用的RPC,互聯網公司往往會使用自己的私有協議,比如騰訊的JCE協議,私有協議不具備通用性,但相比HTTP協議,RPC采用二進制字節碼傳輸,更加高效也更為安全。
  2. 業界提倡的微服務中,服務之間通信方式中RPC是其中之一,RPC可以保證不同服務之間的相互調用,即使是跨語言跨平臺也不是問題,讓構建分布式系統更為容易。
  3. RPC框架都會存在服務降級、流量控制的功能,以保證服務的高可用。

RPC其實是一種技術思想而非規范或協議,常見RPC技術和框架有

  • 應用級的服務框架:阿里的Dubbo/Dubbox、Google的gRPC、Spring Boot/Spring Clound
  • 遠程通信協議:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)
  • 通信框架:MINA、Netty

RPC核心

RPC核心功能是指實現一個RPC最重要的功能模塊即RPC協議部分,一個RPC的核心功能主要由5部分組成分別是:客戶端、客戶端存根、網絡傳輸模式、服務器、服務器存根。

RPC過程
組成 名稱 描述
客戶端 client 服務調用方
客戶端存根 client stub 存放服務器地址信息,將客戶端請求參數數據打包成網絡消息,在通過網路傳輸發送給服務器。
網絡傳輸模式 transfer 底層傳輸,可以是TCP或HTTP。
服務器存根 server stub 接受客戶端發送過來的請求消息并進行解包,然后再調用本地服務進行處理。
服務器 server 服務提供者

RPC原理

一次客戶端對服務器的遠程過程調用,其內部操作可分為以下步驟:

RPC核心功能
RPC調用流程
  1. 客戶端client(caller 服務調用者)
  • 通過本地服務調用的方式調用遠程服務
  1. 客戶端存根 client stub
  • 接收到調用請求后負責將方法和參數等信息序列化(組裝)為能夠在網絡中傳輸的消息體。
  • 調用客戶端句柄,執行傳送參數。
  1. 客戶端存根 client stub
  • 尋找到遠程服務器地址并將消息通過網路發送給服務器
  • 調用本地系統內核發送網絡消息,消息傳遞到遠程主機。
  1. 服務器存根 server stub
  • 接收到客戶端消息后進行解碼即反序列化操作
  • 服務器句柄得到消息并獲取參數
  1. 服務器存根 server stub
  • 根據解碼結果調用本地服務進行處理
  • 執行遠程過程
  1. 服務器 server (callee 服務提供方)
  • 本地業務處理
  1. 服務器 server
  • 服務器處理結果返回給服務器存根
  • 執行過程將結果返回給服務器句柄
  • 服務器句柄返回結果并調用遠程系統內核
  • 消息傳回本地主機
  1. 服務器存根 server stub
  • 序列化結果
  1. 服務器存根 server stub
  • 將序列化結果通過網絡發送至客戶端消費方
  1. 客戶端存根 client stub
  • 接收到服務器返回的消息并進行反序列化解碼
  • 客戶端接收句柄并返回數據
  • 客戶端句柄由內核接收消息
  1. 客戶端 client
  • 服務器消費方獲得最終結果

RPC技術點

一個典型的RPC使用場景中,包含服務發現、負載、容錯、網絡傳輸、序列化等組件,其中RPC協議指明了程序如何進行網絡傳輸和序列化。

RPC框架

實現RPC重點需要實現三個技術,分別是:服務尋址、數據流的序列化和反序列化、網絡傳輸

RPC

服務尋址

遠程過程調用中包含三個角色的節點分別是服務調用方、服務提供方、注冊中心

服務注冊發現機制

可靠的服務尋址方式主要是為了提供服務的發現,是RPC實現的基石。從服務提供方的角度來看,當提供方服務啟動時需要自動向注冊中心注冊機器IP、端口和提供的服務列表,當提供方服務停止時需要向注冊中心注銷服務。提供方需定時向注冊中心發送心跳,當一段時間未收到來自提供方的心跳后,會認為提供方已經停止服務,此時會從注冊中心上摘掉對應的服務。服務調用方啟動時會向注冊中心獲取服務提供方地址列表。

服務尋址可以使用Call ID映射,在本地調用中,函數體是直接通過函數指針來指定的,但在遠程調用中,函數指針是不行的,因為兩個進程的地址空間是完全不一樣的。所以在RPC中所有的函數都必須具有自己的ID,這個ID在所有進程中都是唯一的。

客戶端在做遠程過程調用時,必須附上這個函數ID,還需要在客戶端和服務端分別維護函數和Call ID的對應表。當客戶端需要進行遠程調用時,會差這個對應表找出對應的Call ID,然后將其傳遞給服務器,服務器也通過查對應表來確定客戶端需要調用的函數,最終執行相對應函數的代碼。

序列化和反序列化

遠程過程調用最重要的是序列化與反序列化,因為傳輸的數據庫必須是二進制的,因此客戶端必須將數據序列化為二進制格式傳遞給服務器。為什么需要使用二進制,可直接使用文本嗎?

傳送無符號單字節整數對比

采用原始的二進制可以省掉中間轉換環節,而且數據量會大大減少,效率更高。采用文本方式則需要將整數轉換為字符串后發送,服務端接收時又需要再次進行數據轉換。

客戶端如何將參數傳遞給遠程的函數呢?在本地過程調用中,只需要將參數壓入棧,讓函數自己去棧中讀取即可。但在遠程過程調用中,客戶端跟服務器是不同的進程,不能通過內存來傳遞參數。此時就需要客戶端將參數先轉換為字節流再傳遞給服務器,服務器接收后再將字節流轉換為自己能讀取的格式。而在網絡中只有二進制數據才能傳輸,因此序列化與反序列化的定義也就是將對象轉換成二進制流的過程是序列化,將二進制轉換為對象的過程則是反序列化。

網絡傳輸

遠程調用往往使用在網絡環境中,客戶端和服務器是通過網絡連接的,所有的數據都需要通過網絡傳輸,因此需要一個網絡傳輸層。網絡傳輸層需要將Call ID和序列化后的參數字節流傳遞給服務器,然后再將序列化后的調用結果傳回給客戶端。只要能完成這兩個操作,都可以作為傳輸層使用。因此它所使用的網絡傳輸協議是不限的,只要能完成傳輸即可。盡管大部分RPC框架都是用TCP協議,其實UDP也可以。

TCP連接是最常見的,通常TCP連接可以是按需連接,即需要調用時先建立調用后斷開。也可以是長連接,客戶端和服務器建立連接后保持長期持有,不管此時有無數據包的發送,可以配合心跳檢測機制和定期檢測建立的連接是否存活有效。另外,多個遠程過程調用可以共享同一個連接。

簡單來說,實現一個RCP框架只需要實現三點:

  • Call ID映射:可以直接使用函數字符串,也可以使用整數ID,映射表通常是要一個哈希表。
  • 序列化和反序列化:可使用Protobuf、FlatBuffers等之類
  • 網絡傳輸庫:可使用Socket、Asio、ZeroMQ、Netty等

網絡I/O模型(NIO)

客戶端和服務器通信依賴Socket I/O,網絡I/O模型可分為傳統的阻塞I/O、非阻塞I/O、I/O多路復用、異步I/O。

RPC網絡傳輸協議

在RPC中可選的網絡傳輸方式有很多種,可選的包括TCP、UDP、HTTP,每種協議對整體的性能和效率都有不同的影響。如何選擇一個正確的網絡傳輸協議呢?

  • 基于TCP的RPC

基于TCP協議的RPC調用是由服務調用方和服務提供方建立Socket連接,并由服務調用方通過Socket將需要調用的接口名稱、方法名稱、參數序列化后傳遞給服務提供方,服務提供方反序列化后再利用反射調用相關的方法。最后將結果返回給服務調用方,整個基于TCP協議的RPC調用大致如此。

  • 基于HTTP的RPC

基于HTTP的RPC累加類似于訪問網頁,只是它返回的結果更為單一簡單。首先由服務調用者向服務提供者發送請求,這種請求可能是GET、POST、PUT、DELETE等其中的一種,服務提供者可能會根據不同請求方式做出不同處理,或者某個方法只允許某種請求方式。調用的具體方法則根據URL進行方法調用,方法所需參數可能是對服務器調用方傳輸過去的XML或JSON數據解析后的結果,最后返回JSON或XML的數據結果。

兩種方式對比

基于TCP實現的RPC由于TCP處于協議棧的下層,能夠更加靈活地對協議字段進行定制,減少網路開銷提高性能,實現更大的吞吐量和并發數。但需要更多關注底層復雜的細節,實現代價更高。同時對不同平臺比如安卓、iOS等需要重新開發不同的工具包來進行請求發送和相應的解析,因此工作量大且難以快速響應和滿足用戶需求。

基于HTTP實現的RPC則可以使用JSON和XML格式的請求或響應數據,JSON和XML作為通用的格式開源解析工具已經相當成熟。但由于HTTP是上層協議,發送包含同等內容信息傳輸所占用的字節數會比TCP更高。

因此在同等網絡下通過HTTP傳輸相同的內容效率會比TCP要低,信息傳輸所占的時間也會更長,雖然壓縮數據能夠減少這一差距。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容