RPC(Remote Procedure Call Protocol)遠程過程調用協議,它是一種經過網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議。遠程調用意思就是:被調用方法的具體實現不在程序運行本地,而是在別的某個地方(分佈到各個服務器),調用者只想要函數運算的結果卻不須要了解實現函數的具體細節。也就是說兩臺服務器A,B,一個應用部署在A服務器上,想要調用B服務器上應用提供的函數/方法,因爲不在一個內存空間,不能直接調用,須要經過網絡來表達調用的語義和傳達調用的數據。json
一、Call ID映射
咱們怎麼告訴遠程機器咱們要調用funA而不是funB或者funC呢?在本地調用中函數體是直接經過函數指針來指定的,咱們調用funA編譯器就自動幫咱們調用它相應的函數指針。可是在遠程調用中函數指針是不行的,由於兩個進程的地址空間是徹底不同的。
因此,在RPC中全部的函數都必須有本身的一個ID。這個ID在全部進程中都是惟一肯定的。客戶端在作遠程過程調用時必須附上這個ID。而後咱們還須要在客戶端和服務端分別維護一個 {函數 <–> Call ID} 的對應表。二者的表不必定須要徹底相同但相同的函數對應的Call ID必須相同。當客戶端須要進行遠程調用時,它就查一下這個表,找出相應的Call ID,而後把它傳給服務端,服務端也經過查表,來肯定客戶端須要調用的函數,而後執行相應函數的代碼。
以下圖:
服務器
二、序列化和反序列化
客戶端怎麼把參數值傳給遠程的函數呢?在本地調用中咱們只須要把參數壓到棧裏,而後讓函數本身去棧裏讀就行。可是在遠程過程調用時客戶端和服務端是不一樣的進程不能經過內存來傳遞參數。甚至有時候客戶端和服務端使用的都不是同一種語言(好比服務端用C++,客戶端用Java或者Python)。這時候就須要客戶端把參數先轉成一個字節流(編碼),傳給服務端後,再把字節流轉成本身能讀取的格式(解碼)。這個過程叫序列化和反序列化。同理,從服務端返回的值也須要通過序列化和反序列化的過程。
爲何須要序列化?網絡
三、網絡傳輸
遠程調用每每用在網絡上,客戶端和服務端是經過網絡鏈接的。全部的數據都須要經過網絡傳輸,所以就須要有一個網絡傳輸層。網絡傳輸層須要把Call ID和序列化後的參數字節流傳給服務端,而後再把序列化後的調用結果傳回客戶端。只要能完成這二者的,均可以做爲傳輸層使用。所以,它所使用的協議實際上是不限的,能完成傳輸就行。儘管大部分RPC框架都使用TCP協議,但其實UDP也能夠,而gRPC乾脆就用了HTTP2。
四、RPC的調用流程圖
架構
一、所屬類別不一樣
REST,是Representational State Transfer 的簡寫,中文描述表述性狀態傳遞(是指某個瞬間狀態的資源數據的快照,包括資源數據的內容、表述格式(XML、JSON)等信息。REST 是一種軟件架構風格。這種風格的典型應用,就是HTTP。而RPC ,是 Remote Procedure Call Protocol 的簡寫,中文描述是遠程過程調用,它能夠實現客戶端像調用本地服務(方法)同樣調用服務器的服務(方法)。
RPC能夠基於TCP/UDP,也能夠基於HTTP協議進行傳輸的。
二、使用方式不一樣
從使用上來看,HTTP接口只關注服務提供方,對於客戶端怎麼調用並不關心。接口只要保證有客戶端調用時,返回對應的數據就好了。而RPC則要求客戶端接口保持和服務端的一致。REST是服務端把方法寫好,客戶端並不知道具體方法,客戶端只想獲取資源,因此發起HTTP請求,而服務端接收到請求後根據URI通過一系列的路由才定位到方法上面去,而RPC是服務端提供好方法給客戶端調用,客戶端須要知道服務端的具體類,具體方法,而後像調用本地方法同樣直接調用它。
三、面向對象不一樣
從設計上來看,RPC所謂的遠程過程調用是面向方法的;而REST所謂的Representational state transfer是面向資源的。框架
四、序列化協議不一樣
接口調用一般包含兩個部分,序列化和通訊協議。REST是基於HTTP協議,而RPC能夠基於TCP/UDP,也能夠基於 HTTP協議進行傳輸。常見的序列化協議有:json、xml、hession、protobuf、thrift、text、bytes等,REST一般使用的是JSON或者XML,而RPC使用的是JSON-RPC或者XML-RPC。ide
參考博文:
(1) https://baijiahao.baidu.com/s?id=1637758852641939872&wfr=spider&for=pc (rpc與rest的比較理解與實現)函數