中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

RPC是什么?

發布時間:2020-06-24 08:06:00 來源:網絡 閱讀:559 作者:shaiberni 欄目:軟件技術

目錄
1、什么是RPC?
2、典型RPC調用框架
3、Thrift框架介紹
1、什么是RPC?
(1)RPC(remote procedure call):遠程調用過程。

  服務器A部署應用a,服務器B部署應用b,當A服務器調用B服務器上的b應用的函數或者方法時,因為不在同一內存空間,不能直接調用,必須通過網絡來表達調用的語義傳達調用的數據。

既然是調用B機器上的服務,那A機器自己也創建一個這個服務不就也可以調用了么。原理上是可以這么做,但是隨著計算機的橫向發展,集群的出現,使得多臺機器部署成一個集群來對外提供服務。無法在一個進程內甚至同一臺計算機上完成的需求就得需要RPC來實現了。

RPC的框架很多,比如最早的額CORBA,Java RMI,Web Service的RPC風格,Hessian,Thrift,甚至是Rest API。

(2) 本地過程調用過程

   RPC就是要像調用本地的函數一樣去調遠程函數。在研究RPC前,我們先看看本地調用是怎么調的。假設我們要調用函數Multiply來計算lvalue * rvalue的結果:

1 int Multiply(int l, int r) {

2 int y = l * r;

3 return y;

4 }

5

6 int lvalue = 10;

7 int rvalue = 20;

8 int l_times_r = Multiply(lvalue, rvalue);

  那么在第8行時,我們實際上執行了以下操作:

將 lvalue 和 rvalue 的值壓棧

進入Multiply函數,取出棧中的值10 和 20,將其賦予 l 和 r

執行第2行代碼,計算 l * r ,并將結果存在 y

將 y 的值壓棧,然后從Multiply返回

第8行,從棧中取出返回值 200 ,并賦值給 l_times_r

  以上5步就是執行本地調用的過程。

(3)遠程過程調用帶來的新問題

 在遠程調用時,我們需要執行的函數體是在遠程的機器上的,也就是說,Multiply是在另一個進程中執行的。這就帶來了幾個新問題:

Call ID映射。我們怎么告訴遠程機器我們要調用Multiply,而不是Add或者FooBar呢?在本地調用中,函數體是直接通過函數指針來指定的,我們調用Multiply,編譯器就自動幫我們調用它相應的函數指針。但是在遠程調用中,函數指針是不行的,因為兩個進程的地址空間是完全不一樣的。所以,在RPC中,所有的函數都必須有自己的一個ID。這個ID在所有進程中都是唯一確定的。客戶端在做遠程過程調用時,必須附上這個ID。然后我們還需要在客戶端和服務端分別維護一個 {函數 <--> Call ID} 的對應表。兩者的表不一定需要完全相同,但相同的函數對應的Call ID必須相同。當客戶端需要進行遠程調用時,它就查一下這個表,找出相應的Call ID,然后把它傳給服務端,服務端也通過查表,來確定客戶端需要調用的函數,然后執行相應函數的代碼。

序列化和反序列化。客戶端怎么把參數值傳給遠程的函數呢?在本地調用中,我們只需要把參數壓到棧里,然后讓函數自己去棧里讀就行。但是在遠程過程調用時,客戶端跟服務端是不同的進程,不能通過內存來傳遞參數。甚至有時候客戶端和服務端使用的都不是同一種語言(比如服務端用C++,客戶端用Java或者Python)。這時候就需要客戶端把參數先轉成一個字節流,傳給服務端后,再把字節流轉成自己能讀取的格式。這個過程叫序列化和反序列化。同理,從服務端返回的值也需要序列化反序列化的過程。

網絡傳輸。遠程調用往往用在網絡上,客戶端和服務端是通過網絡連接的。所有的數據都需要通過網絡傳輸,因此就需要有一個網絡傳輸層。網絡傳輸層需要把Call ID和序列化后的參數字節流傳給服務端,然后再把序列化后的調用結果傳回客戶端。只要能完成這兩者的,都可以作為傳輸層使用。因此,它所使用的協議其實是不限的,能完成傳輸就行。盡管大部分RPC框架都使用TCP協議,但其實UDP也可以,而gRPC干脆就用了HTTP2。Java的Netty也屬于這層的東西。

 所以,要實現一個RPC框架,其實只需要把以上三點實現了就基本完成了。

 Call ID映射可以直接使用函數字符串,也可以使用整數ID。映射表一般就是一個哈希表。

 序列化反序列化可以自己寫,也可以使用Protobuf或者FlatBuffers之類的。

 網絡傳輸庫可以自己寫socket,或者用asio,ZeroMQ,Netty之類。

2、典型RPC調用框架

RPC的實現和調用框架很多,簡單介紹其中幾種比較典型的:

RMI(RemoteManagementInterface),利用java.rmi包實現,基于Java遠程方法協議(Java Remote Method Protocol) 和java的原生序列化。

Hessian,是一個輕量級的remoting onhttp工具,使用簡單的方法提供了RMI的功能。 基于HTTP協議,采用二進制編解碼。

protobuf-rpc-pro,是一個Java類庫,提供了基于 Google 的 Protocol Buffers 協議的遠程方法調用的框架。基于 Netty 底層的 NIO 技術。支持 TCP 重用/ keep-alive、SSL加密、RPC 調用取消操作、嵌入式日志等能。

Thrift,是一種可伸縮的跨語言服務的軟件框架。它擁有功能強大的代碼生成引擎,無縫地支持C + +,C#,Java,Python和PHP和Ruby。thrift允許你定義一個描述文件,描述數據類型和服務接口。依據該文件,編譯器方便地生成RPC客戶端和服務器通信代碼。最初由facebook開發用做系統內個語言之間的RPC通信,2007年由facebook貢獻到apache基金 ,現在是apache下的opensource之一 。支持多種語言之間的RPC方式的通信:php語言client可以構造一個對象,調用相應的服務方法來調用java語言的服務,跨越語言的C/S RPC調用。底層通訊基于SOCKET。

Avro,出自Hadoop之父Doug Cutting, 在Thrift已經相當流行的情況下推出Avro的目標不僅是提供一套類似Thrift的通訊中間件,更是要建立一個新的,標準性的云計算的數據交換和存儲的Protocol。支持HTTP,TCP兩種協議。

3、Thrift框架介紹
最常見的RPC工具是Facebook開源的Thrift RPC框架。

Thrift是一個跨語言的服務部署框架,最初由Facebook于2007年開發,2008年進入Apache開源項目。Thrift通過一個中間語言(IDL, 接口定義語言)來定義RPC的接口和數據類型,然后通過一個編譯器生成不同語言的代碼(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml),并由生成的代碼負責RPC協議層和傳輸層的實現。

Thrift實際上是實現了C/S模式,通過代碼生成工具將接口定義文件生成服務器端和客戶端代碼(可以為不同語言),從而實現服務端和客戶端跨語言的支持。用戶在Thirft描述文件中聲明自己的服務,這些服務經過編譯后會生成相應語言的代碼文件,然后用戶實現服務(客戶端調用服務,服務器端提服務)便可以了。其中protocol(協議層, 定義數據傳輸格式,可以為二進制或者XML等)和transport(傳輸層,定義數據傳輸方式,可以為TCP/IP傳輸,內存共享或者文件共享等)被用作運行時庫。

Thrift的協議棧如下圖所示:

重試

在Client和Server的最頂層都是用戶自定義的處理邏輯,也就是說用戶只需要編寫用戶邏輯,就可以完成整套的RPC調用流程。用戶邏輯的下一層是Thrift自動生成的代碼,這些代碼主要用于結構化數據的解析,發送和接收,同時服務器端的自動生成代碼中還包含了RPC請求的轉發(Client的A調用轉發到Server A函數進行處理)。

協議棧的其他模塊都是Thrift的運行時模塊:

底層IO模塊,負責實際的數據傳輸,包括Socket,文件,或者壓縮數據流等。

TTransport負責以字節流方式發送和接收Message,是底層IO模塊在Thrift框架中的實現,每一個底層IO模塊都會有一個對應TTransport來負責Thrift的字節流(Byte Stream)數據在該IO模塊上的傳輸。例如TSocket對應Socket傳輸,TFileTransport對應文件傳輸。

TProtocol主要負責結構化數據組裝成Message,或者從Message結構中讀出結構化數據。TProtocol將一個有類型的數據轉化為字節流以交給TTransport進行傳輸,或者從TTransport中讀取一定長度的字節數據轉化為特定類型的數據。如int32會被TBinaryProtocol Encode為一個四字節的字節數據,或者TBinaryProtocol從TTransport中取出四個字節的數據Decode為int32。

TServer負責接收Client的請求,并將請求轉發到Processor進行處理。TServer主要任務就是高效的接受Client的請求,特別是在高并發請求的情況下快速完成請求。

Processor(或者TProcessor)負責對Client的請求做出相應,包括RPC請求轉發,調用參數解析和用戶邏輯調用,返回值寫回等處理步驟。Processor是服務器端從Thrift框架轉入用戶邏輯的關鍵流程。Processor同時也負責向Message結構中寫入數據或者讀出數據。

Thrift的模塊設計非常好,在每一個層次都可以根據自己的需要選擇合適的實現方式。同時也應該注意到Thrift目前的特性并不是在所有的程序語言中都支持。例如C++實現中有TDenseProtocol沒有TTupleProtocol,而Java實現中有TTupleProtocol沒有TDenseProtocol。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

通城县| 洮南市| 甘孜| 甘肃省| 九龙县| 金门县| 深泽县| 嘉禾县| 宁夏| 赤水市| 抚顺县| 思南县| 五大连池市| 大港区| 盐城市| 泗水县| 吴堡县| 同德县| 进贤县| 南昌市| 寿光市| 福建省| 兴国县| 诏安县| 抚顺市| 油尖旺区| 左贡县| 册亨县| 武宁县| 肥东县| 天祝| 云和县| 清水县| 惠水县| 云霄县| 楚雄市| 阿荣旗| 子长县| 张家口市| 永州市| 喀喇|