精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

花了一個星期,我終于把RPC框架整明白了!

原創(chuàng)
開發(fā) 架構(gòu) 開發(fā)工具
RPC(Remote Procedure Call):遠(yuǎn)程過程調(diào)用,它是一種通過網(wǎng)絡(luò)從遠(yuǎn)程計算機(jī)程序上請求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的思想。

【51CTO.com原創(chuàng)稿件】RPC(Remote Procedure Call):遠(yuǎn)程過程調(diào)用,它是一種通過網(wǎng)絡(luò)從遠(yuǎn)程計算機(jī)程序上請求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的思想。

RPC 是一種技術(shù)思想而非一種規(guī)范或協(xié)議,常見 RPC 技術(shù)和框架有:

  • 應(yīng)用級的服務(wù)框架:阿里的 Dubbo/Dubbox、Google gRPC、Spring Boot/Spring Cloud。
  • 遠(yuǎn)程通信協(xié)議:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。
  • 通信框架:MINA 和 Netty。

目前流行的開源 RPC 框架還是比較多的,有阿里巴巴的 Dubbo、Facebook 的 Thrift、Google 的 gRPC、Twitter 的 Finagle 等。

下面重點(diǎn)介紹三種:

  • gRPC:是 Google 公布的開源軟件,基于***的 HTTP 2.0 協(xié)議,并支持常見的眾多編程語言。RPC 框架是基于 HTTP 協(xié)議實(shí)現(xiàn)的,底層使用到了 Netty 框架的支持。
  • Thrift:是 Facebook 的開源 RPC 框架,主要是一個跨語言的服務(wù)開發(fā)框架。

用戶只要在其之上進(jìn)行二次開發(fā)就行,應(yīng)用對于底層的 RPC 通訊等都是透明的。不過這個對于用戶來說需要學(xué)習(xí)特定領(lǐng)域語言這個特性,還是有一定成本的。

  • Dubbo:是阿里集團(tuán)開源的一個極為出名的 RPC 框架,在很多互聯(lián)網(wǎng)公司和企業(yè)應(yīng)用中廣泛使用。協(xié)議和序列化框架都可以插拔是極其鮮明的特色。

完整的 RPC 框架

在一個典型 RPC 的使用場景中,包含了服務(wù)發(fā)現(xiàn)、負(fù)載、容錯、網(wǎng)絡(luò)傳輸、序列化等組件,其中“RPC 協(xié)議”就指明了程序如何進(jìn)行網(wǎng)絡(luò)傳輸和序列化。

 

圖 1:完整 RPC 架構(gòu)圖

如下是 Dubbo 的設(shè)計架構(gòu)圖,分層清晰,功能復(fù)雜:

 

圖 2:Dubbo 架構(gòu)圖

[[268129]] 

RPC 核心功能

RPC 的核心功能是指實(shí)現(xiàn)一個 RPC 最重要的功能模塊,就是上圖中的”RPC 協(xié)議”部分:

 

圖 3:RPC 核心功能

一個 RPC 的核心功能主要有 5 個部分組成,分別是:客戶端、客戶端 Stub、網(wǎng)絡(luò)傳輸模塊、服務(wù)端 Stub、服務(wù)端等。

 

圖 4:RPC 核心功能圖

下面分別介紹核心 RPC 框架的重要組成:

  • 客戶端(Client):服務(wù)調(diào)用方。
  • 客戶端存根(Client Stub):存放服務(wù)端地址信息,將客戶端的請求參數(shù)數(shù)據(jù)信息打包成網(wǎng)絡(luò)消息,再通過網(wǎng)絡(luò)傳輸發(fā)送給服務(wù)端。
  • 服務(wù)端存根(Server Stub):接收客戶端發(fā)送過來的請求消息并進(jìn)行解包,然后再調(diào)用本地服務(wù)進(jìn)行處理。
  • 服務(wù)端(Server):服務(wù)的真正提供者。
  • Network Service:底層傳輸,可以是 TCP 或 HTTP。

Python 自帶 RPC Demo

Server.py:

  1. from SimpleXMLRPCServer import SimpleXMLRPCServer    
  2. def fun_add(a,b): 
  3.     totle = a + b  
  4.     return totle 
  5. if __name__ == '__main__'
  6.     s = SimpleXMLRPCServer(('0.0.0.0', 8080))   #開啟xmlrpcserver 
  7.     s.register_function(fun_add)                #注冊函數(shù)fun_add 
  8.     print "server is online..." 
  9.     s.serve_forever()                           #開啟循環(huán)等待 

Client.py:

  1. from xmlrpclib import ServerProxy            #導(dǎo)入xmlrpclib的包 
  2. s = ServerProxy("http://172.171.5.205:8080") #定義xmlrpc客戶端 
  3. print s.fun_add(2,3)         

開啟服務(wù)端:

 

開啟客戶端:

 

Wireshark 抓包分析過程

客戶端去往服務(wù)端:

  • 客戶端 IP:172.171.4.176
  • 服務(wù)端 IP:172.171.5.95

通信使用 HTTP 協(xié)議,XML 文件傳輸格式。傳輸?shù)淖侄伟ǎ悍椒?methodName,兩個參數(shù) 2,3。

 

圖 5:Request 抓包

服務(wù)端返回結(jié)果,字段返回值 Value,結(jié)果是 5:

 

圖 6:Response 抓包

在這兩次網(wǎng)絡(luò)傳輸中使用了 HTTP 協(xié)議,建立 HTTP 協(xié)議之間有 TCP 三次握手,斷開 HTTP 協(xié)議時有 TCP 四次揮手。

 

圖 7:基于 HTTP 協(xié)議的 RPC 連接過程

詳細(xì)調(diào)用過程

Python 自帶 RPC 的 Demo 小程序的實(shí)現(xiàn)過程,流程和分工角色可以用下圖來表示:

 

圖 8:RPC 調(diào)用詳細(xì)流程圖

一次 RPC 調(diào)用流程如下:

  • 服務(wù)消費(fèi)者(Client 客戶端)通過本地調(diào)用的方式調(diào)用服務(wù)。
  • 客戶端存根(Client Stub)接收到調(diào)用請求后負(fù)責(zé)將方法、入?yún)⒌刃畔⑿蛄谢?組裝)成能夠進(jìn)行網(wǎng)絡(luò)傳輸?shù)南Ⅲw。
  • 客戶端存根(Client Stub)找到遠(yuǎn)程的服務(wù)地址,并且將消息通過網(wǎng)絡(luò)發(fā)送給服務(wù)端。
  • 服務(wù)端存根(Server Stub)收到消息后進(jìn)行解碼(反序列化操作)。
  • 服務(wù)端存根(Server Stub)根據(jù)解碼結(jié)果調(diào)用本地的服務(wù)進(jìn)行相關(guān)處理
  • 服務(wù)端(Server)本地服務(wù)業(yè)務(wù)處理。
  • 處理結(jié)果返回給服務(wù)端存根(Server Stub)。
  • 服務(wù)端存根(Server Stub)序列化結(jié)果。
  • 服務(wù)端存根(Server Stub)將結(jié)果通過網(wǎng)絡(luò)發(fā)送至消費(fèi)方。
  • 客戶端存根(Client Stub)接收到消息,并進(jìn)行解碼(反序列化)。
  • 服務(wù)消費(fèi)方得到最終結(jié)果。

[[268131]] 

RPC 核心之功能實(shí)現(xiàn)

RPC 的核心功能主要由 5 個模塊組成,如果想要自己實(shí)現(xiàn)一個 RPC,最簡單的方式要實(shí)現(xiàn)三個技術(shù)點(diǎn),分別是:

  • 服務(wù)尋址
  • 數(shù)據(jù)流的序列化和反序列化
  • 網(wǎng)絡(luò)傳輸

服務(wù)尋址

服務(wù)尋址可以使用 Call ID 映射。在本地調(diào)用中,函數(shù)體是直接通過函數(shù)指針來指定的,但是在遠(yuǎn)程調(diào)用中,函數(shù)指針是不行的,因?yàn)閮蓚€進(jìn)程的地址空間是完全不一樣的。

所以在 RPC 中,所有的函數(shù)都必須有自己的一個 ID。這個 ID 在所有進(jìn)程中都是唯一確定的。

客戶端在做遠(yuǎn)程過程調(diào)用時,必須附上這個 ID。然后我們還需要在客戶端和服務(wù)端分別維護(hù)一個函數(shù)和Call ID的對應(yīng)表。

當(dāng)客戶端需要進(jìn)行遠(yuǎn)程調(diào)用時,它就查一下這個表,找出相應(yīng)的 Call ID,然后把它傳給服務(wù)端,服務(wù)端也通過查表,來確定客戶端需要調(diào)用的函數(shù),然后執(zhí)行相應(yīng)函數(shù)的代碼。

實(shí)現(xiàn)方式:服務(wù)注冊中心。

要調(diào)用服務(wù),首先你需要一個服務(wù)注冊中心去查詢對方服務(wù)都有哪些實(shí)例。Dubbo 的服務(wù)注冊中心是可以配置的,官方推薦使用 Zookeeper。

實(shí)現(xiàn)案例:RMI(Remote Method Invocation,遠(yuǎn)程方法調(diào)用)也就是 RPC 本身的實(shí)現(xiàn)方式。

 

圖 9:RMI 架構(gòu)圖

Registry(服務(wù)發(fā)現(xiàn)):借助 JNDI 發(fā)布并調(diào)用了 RMI 服務(wù)。實(shí)際上,JNDI 就是一個注冊表,服務(wù)端將服務(wù)對象放入到注冊表中,客戶端從注冊表中獲取服務(wù)對象。

RMI 服務(wù)在服務(wù)端實(shí)現(xiàn)之后需要注冊到 RMI Server 上,然后客戶端從指定的 RMI 地址上 Lookup 服務(wù),調(diào)用該服務(wù)對應(yīng)的方法即可完成遠(yuǎn)程方法調(diào)用。

Registry 是個很重要的功能,當(dāng)服務(wù)端開發(fā)完服務(wù)之后,要對外暴露,如果沒有服務(wù)注冊,則客戶端是無從調(diào)用的,即使服務(wù)端的服務(wù)就在那里。

序列化和反序列化

客戶端怎么把參數(shù)值傳給遠(yuǎn)程的函數(shù)呢?在本地調(diào)用中,我們只需要把參數(shù)壓到棧里,然后讓函數(shù)自己去棧里讀就行。

但是在遠(yuǎn)程過程調(diào)用時,客戶端跟服務(wù)端是不同的進(jìn)程,不能通過內(nèi)存來傳遞參數(shù)。

這時候就需要客戶端把參數(shù)先轉(zhuǎn)成一個字節(jié)流,傳給服務(wù)端后,再把字節(jié)流轉(zhuǎn)成自己能讀取的格式。

只有二進(jìn)制數(shù)據(jù)才能在網(wǎng)絡(luò)中傳輸,序列化和反序列化的定義是:

  • 將對象轉(zhuǎn)換成二進(jìn)制流的過程叫做序列化
  • 將二進(jìn)制流轉(zhuǎn)換成對象的過程叫做反序列化

這個過程叫序列化和反序列化。同理,從服務(wù)端返回的值也需要序列化反序列化的過程。

網(wǎng)絡(luò)傳輸

網(wǎng)絡(luò)傳輸:遠(yuǎn)程調(diào)用往往用在網(wǎng)絡(luò)上,客戶端和服務(wù)端是通過網(wǎng)絡(luò)連接的。

所有的數(shù)據(jù)都需要通過網(wǎng)絡(luò)傳輸,因此就需要有一個網(wǎng)絡(luò)傳輸層。網(wǎng)絡(luò)傳輸層需要把 Call ID 和序列化后的參數(shù)字節(jié)流傳給服務(wù)端,然后再把序列化后的調(diào)用結(jié)果傳回客戶端。

只要能完成這兩者的,都可以作為傳輸層使用。因此,它所使用的協(xié)議其實(shí)是不限的,能完成傳輸就行。

盡管大部分 RPC 框架都使用 TCP 協(xié)議,但其實(shí) UDP 也可以,而 gRPC 干脆就用了 HTTP2。

TCP 的連接是最常見的,簡要分析基于 TCP 的連接:通常 TCP 連接可以是按需連接(需要調(diào)用的時候就先建立連接,調(diào)用結(jié)束后就立馬斷掉),也可以是長連接(客戶端和服務(wù)器建立起連接之后保持長期持有,不管此時有無數(shù)據(jù)包的發(fā)送,可以配合心跳檢測機(jī)制定期檢測建立的連接是否存活有效),多個遠(yuǎn)程過程調(diào)用共享同一個連接。

所以,要實(shí)現(xiàn)一個 RPC 框架,只需要把以下三點(diǎn)實(shí)現(xiàn)了就基本完成了:

  • Call ID 映射:可以直接使用函數(shù)字符串,也可以使用整數(shù) ID。映射表一般就是一個哈希表。
  • 序列化反序列化:可以自己寫,也可以使用 Protobuf 或者 FlatBuffers 之類的。
  • 網(wǎng)絡(luò)傳輸庫:可以自己寫 Socket,或者用 Asio,ZeroMQ,Netty 之類。

RPC 核心之網(wǎng)絡(luò)傳輸協(xié)議

在第三節(jié)中說明了要實(shí)現(xiàn)一個 RPC,需要選擇網(wǎng)絡(luò)傳輸?shù)姆绞健?/p>

 

圖 10:網(wǎng)絡(luò)傳輸

在 RPC 中可選的網(wǎng)絡(luò)傳輸方式有多種,可以選擇 TCP 協(xié)議、UDP 協(xié)議、HTTP 協(xié)議。

每一種協(xié)議對整體的性能和效率都有不同的影響,如何選擇一個正確的網(wǎng)絡(luò)傳輸協(xié)議呢?首先要搞明白各種傳輸協(xié)議在 RPC 中的工作方式。

基于 TCP 協(xié)議的 RPC 調(diào)用

由服務(wù)的調(diào)用方與服務(wù)的提供方建立 Socket 連接,并由服務(wù)的調(diào)用方通過 Socket 將需要調(diào)用的接口名稱、方法名稱和參數(shù)序列化后傳遞給服務(wù)的提供方,服務(wù)的提供方反序列化后再利用反射調(diào)用相關(guān)的方法。

***將結(jié)果返回給服務(wù)的調(diào)用方,整個基于 TCP 協(xié)議的 RPC 調(diào)用大致如此。

但是在實(shí)例應(yīng)用中則會進(jìn)行一系列的封裝,如 RMI 便是在 TCP 協(xié)議上傳遞可序列化的 Java 對象。

基于 HTTP 協(xié)議的 RPC 調(diào)用

該方法更像是訪問網(wǎng)頁一樣,只是它的返回結(jié)果更加單一簡單。

其大致流程為:由服務(wù)的調(diào)用者向服務(wù)的提供者發(fā)送請求,這種請求的方式可能是 GET、POST、PUT、DELETE 等中的一種,服務(wù)的提供者可能會根據(jù)不同的請求方式做出不同的處理,或者某個方法只允許某種請求方式。

而調(diào)用的具體方法則是根據(jù) URL 進(jìn)行方法調(diào)用,而方法所需要的參數(shù)可能是對服務(wù)調(diào)用方傳輸過去的 XML 數(shù)據(jù)或者 JSON 數(shù)據(jù)解析后的結(jié)果,***返回 JOSN 或者 XML 的數(shù)據(jù)結(jié)果。

由于目前有很多開源的 Web 服務(wù)器,如 Tomcat,所以其實(shí)現(xiàn)起來更加容易,就像做 Web 項(xiàng)目一樣。

兩種方式對比

基于 TCP 的協(xié)議實(shí)現(xiàn)的 RPC 調(diào)用,由于 TCP 協(xié)議處于協(xié)議棧的下層,能夠更加靈活地對協(xié)議字段進(jìn)行定制,減少網(wǎng)絡(luò)開銷,提高性能,實(shí)現(xiàn)更大的吞吐量和并發(fā)數(shù)。

但是需要更多關(guān)注底層復(fù)雜的細(xì)節(jié),實(shí)現(xiàn)的代價更高。同時對不同平臺,如安卓,iOS 等,需要重新開發(fā)出不同的工具包來進(jìn)行請求發(fā)送和相應(yīng)解析,工作量大,難以快速響應(yīng)和滿足用戶需求。

基于 HTTP 協(xié)議實(shí)現(xiàn)的 RPC 則可以使用 JSON 和 XML 格式的請求或響應(yīng)數(shù)據(jù)。

而 JSON 和 XML 作為通用的格式標(biāo)準(zhǔn)(使用 HTTP 協(xié)議也需要序列化和反序列化,不過這不是該協(xié)議下關(guān)心的內(nèi)容,成熟的 Web 程序已經(jīng)做好了序列化內(nèi)容),開源的解析工具已經(jīng)相當(dāng)成熟,在其上進(jìn)行二次開發(fā)會非常便捷和簡單。

但是由于 HTTP 協(xié)議是上層協(xié)議,發(fā)送包含同等內(nèi)容的信息,使用 HTTP 協(xié)議傳輸所占用的字節(jié)數(shù)會比使用 TCP 協(xié)議傳輸所占用的字節(jié)數(shù)更高。

因此在同等網(wǎng)絡(luò)下,通過 HTTP 協(xié)議傳輸相同內(nèi)容,效率會比基于 TCP 協(xié)議的數(shù)據(jù)效率要低,信息傳輸所占用的時間也會更長,當(dāng)然壓縮數(shù)據(jù),能夠縮小這一差距。

使用 RabbitMQ 的 RPC 架構(gòu)

在 OpenStack 中服務(wù)與服務(wù)之間使用 RESTful API 調(diào)用,而在服務(wù)內(nèi)部則使用 RPC 調(diào)用各個功能模塊。

正是由于使用了 RPC 來解耦服務(wù)內(nèi)部功能模塊,使得 OpenStack 的服務(wù)擁有擴(kuò)展性強(qiáng),耦合性低等優(yōu)點(diǎn)。

OpenStack 的 RPC 架構(gòu)中,加入了消息隊(duì)列 RabbitMQ,這樣做的目的是為了保證 RPC 在消息傳遞過程中的安全性和穩(wěn)定性。

下面分析 OpenStack 中使用 RabbitMQ 如何實(shí)現(xiàn) RPC 的調(diào)用。

RabbitMQ 簡介

以下摘錄自知乎:

對于初學(xué)者,舉一個飯店的例子來解釋這三個分別是什么吧。不是***恰當(dāng),但是應(yīng)該足以解釋這三者的區(qū)別。

RPC:假設(shè)你是一個飯店里的服務(wù)員,顧客向你點(diǎn)菜,但是你不會做菜,所以你采集了顧客要點(diǎn)什么之后告訴后廚去做顧客點(diǎn)的菜,這叫 RPC(remote procedure call),因?yàn)閺N房的廚師相對于服務(wù)員而言是另外一個人(在計算機(jī)的世界里就是 Remote 的機(jī)器上的一個進(jìn)程)。廚師做好了的菜就是RPC的返回值。

任務(wù)隊(duì)列和消息隊(duì)列:本質(zhì)都是隊(duì)列,所以就只舉一個任務(wù)隊(duì)列的例子。假設(shè)這個飯店在高峰期顧客很多,而廚師只有很少的幾個,所以服務(wù)員們不得不把單子按下單順序放在廚房的桌子上,供廚師們一個一個做,這一堆單子就是任務(wù)隊(duì)列,廚師們每做完一個菜,就從桌子上的訂單里再取出一個單子繼續(xù)做菜。

角色分擔(dān)如下圖:

 

圖 11:RabbitMQ 在 RPC 中角色

使用 RabbitMQ 的好處:

  • 同步變異步:可以使用線程池將同步變成異步,但是缺點(diǎn)是要自己實(shí)現(xiàn)線程池,并且強(qiáng)耦合。使用消息隊(duì)列可以輕松將同步請求變成異步請求。
  • 低內(nèi)聚高耦合:解耦,減少強(qiáng)依賴。
  • 流量削峰:通過消息隊(duì)列設(shè)置請求***值,超過閥值的拋棄或者轉(zhuǎn)到錯誤界面。
  • 網(wǎng)絡(luò)通信性能提高:TCP 的創(chuàng)建和銷毀開銷大,創(chuàng)建 3 次握手,銷毀 4 次分手,高峰時成千上萬條的鏈接會造成資源的巨大浪費(fèi),而且操作系統(tǒng)每秒處理 TCP 的數(shù)量也是有數(shù)量限制的,必定造成性能瓶頸。

RabbitMQ 采用信道通信,不采用 TCP 直接通信。一條線程一條信道,多條線程多條信道,公用一個 TCP 連接。

一條 TCP 連接可以容納***條信道(硬盤容量足夠的話),不會造成性能瓶頸。

RabbitMQ 的三種類型的交換器

RabbitMQ 使用 Exchange(交換機(jī))和 Queue(隊(duì)列)來實(shí)現(xiàn)消息隊(duì)列。

在 RabbitMQ 中一共有三種交換機(jī)類型,每一種交換機(jī)類型都有很鮮明的特征。

基于這三種交換機(jī)類型,OpenStack 完成兩種 RPC 的調(diào)用方式。首先簡單介紹三種交換機(jī)。

 

圖 12:RabbitMQ 架構(gòu)圖

①廣播式交換器類型(Fanout)

該類交換器不分析所接收到消息中的 Routing Key,默認(rèn)將消息轉(zhuǎn)發(fā)到所有與該交換器綁定的隊(duì)列中去。

 

圖 13:廣播式交換機(jī)

②直接式交換器類型(Direct)

該類交換器需要精確匹配 Routing Key 與 Binding Key,如消息的 Routing Key = Cloud,那么該條消息只能被轉(zhuǎn)發(fā)至 Binding Key = Cloud 的消息隊(duì)列中去。

 

圖 14:直接式交換機(jī)

③主題式交換器(Topic Exchange)

該類交換器通過消息的 Routing Key 與 Binding Key 的模式匹配,將消息轉(zhuǎn)發(fā)至所有符合綁定規(guī)則的隊(duì)列中。

Binding Key 支持通配符,其中“*”匹配一個詞組,“#”匹配多個詞組(包括零個)。

 

圖 15:主題式交換機(jī)

注:以上四張圖片來自博客園,如有侵權(quán),請聯(lián)系作者:https://www.cnblogs.com/dwlsxj/p/RabbitMQ.html。

當(dāng)生產(chǎn)者發(fā)送消息 Routing Key=F.C.E 的時候,這時候只滿足 Queue1,所以會被路由到 Queue 中。

如果 Routing Key=A.C.E 這時候會被同時路由到 Queue1 和 Queue2 中,如果 Routing Key=A.F.B 時,這里只會發(fā)送一條消息到 Queue2 中。

Nova 基于 RabbitMQ 實(shí)現(xiàn)兩種 RPC 調(diào)用:

  • RPC.CALL(調(diào)用)
  • RPC.CAST(通知)

其中 RPC.CALL 基于請求與響應(yīng)方式,RPC.CAST 只是提供單向請求,兩種 RPC 調(diào)用方式在 Nova 中均有典型的應(yīng)用場景。

RPC.CALL

RPC.CALL 是一種雙向通信流程,即 RabbitMQ 接收消息生產(chǎn)者生成的系統(tǒng)請求消息,消息消費(fèi)者經(jīng)過處理之后將系統(tǒng)相應(yīng)結(jié)果反饋給調(diào)用程序。

 

圖 16:RPC.CALL 原理圖

一個用戶通過 Dashboard 創(chuàng)建一個虛擬機(jī),界面經(jīng)過消息封裝后發(fā)送給 NOVA-API。

NOVA-API 作為消息生產(chǎn)者,將該消息以 RPC.CALL 方式通過 Topic 交換器轉(zhuǎn)發(fā)至消息隊(duì)列。

此時,Nova-Compute 作為消息消費(fèi)者,接收該信息并通過底層虛擬化軟件執(zhí)行相應(yīng)虛擬機(jī)的啟動進(jìn)程。

待用戶虛擬機(jī)成功啟動之后,Nova-Compute 作為消息生產(chǎn)者通過 Direct 交換器和響應(yīng)的消息隊(duì)列將虛擬機(jī)啟動成功響應(yīng)消息反饋給 Nova-API。

此時 Nova-API 作為消息消費(fèi)者接收該消息并通知用戶虛擬機(jī)啟動成功。

 

RPC.CALL 工作原理如下圖:

 

圖 17:RPC.CALL 具體實(shí)現(xiàn)圖

工作流程:

  • 客戶端創(chuàng)建 Message 時指定 reply_to 隊(duì)列名、correlation_id 標(biāo)記調(diào)用者。
  • 通過隊(duì)列,服務(wù)端收到消息。調(diào)用函數(shù)處理,然后返回。
  • 返回的隊(duì)列是 reply_to 指定的隊(duì)列,并攜帶 correlation_id。
  • 返回消息到達(dá)客戶端,客戶端根據(jù) correlation_id 判斷是哪一個函數(shù)的調(diào)用返回。

如果有多個線程同時進(jìn)行遠(yuǎn)程方法調(diào)用,這時建立在 Client Server 之間的 Socket 連接上會有很多雙方發(fā)送的消息傳遞,前后順序也可能是隨機(jī)的。

Server 處理完結(jié)果后,將結(jié)果消息發(fā)送給 Client,Client 收到很多消息,怎么知道哪個消息結(jié)果是原先哪個線程調(diào)用的?

Client 線程每次通過 Socket 調(diào)用一次遠(yuǎn)程接口前,生成一個唯一的 ID,即 Request ID(Request ID必需保證在一個 Socket 連接里面是唯一的),一般常常使用 AtomicLong 從 0 開始累計數(shù)字生成唯一 ID。

RPC.CAST

RPC.CAST 的遠(yuǎn)程調(diào)用流程與 RPC.CALL 類似,只是缺少了系統(tǒng)消息響應(yīng)流程。

一個 Topic 消息生產(chǎn)者發(fā)送系統(tǒng)請求消息到 Topic 交換器,Topic 交換器根據(jù)消息的 Routing Key 將消息轉(zhuǎn)發(fā)至共享消息隊(duì)列。

與共享消息隊(duì)列相連的所有 Topic 消費(fèi)者接收該系統(tǒng)請求消息,并把它傳遞給響應(yīng)的服務(wù)端進(jìn)行處理。

其調(diào)用流程如圖所示:

 

圖 18:RPC.CAST 原理圖

連接設(shè)計

RabbitMQ 實(shí)現(xiàn)的 RPC 對網(wǎng)絡(luò)的一般設(shè)計思路:消費(fèi)者是長連接,發(fā)送者是短連接。但可以自由控制長連接和短連接。

一般消費(fèi)者是長連接,隨時準(zhǔn)備接收處理消息;而且涉及到 RabbitMQ Queues、Exchange 的 auto-deleted 等沒特殊需求沒必要做短連接。發(fā)送者可以使用短連接,不會長期占住端口號,節(jié)省端口資源。

Nova 中 RPC 代碼設(shè)計:

 

簡單對比 RPC 和 Restful API

RESTful API 架構(gòu)

REST ***的幾個特點(diǎn)為:資源、統(tǒng)一接口、URI 和無狀態(tài)。

①資源

所謂"資源",就是網(wǎng)絡(luò)上的一個實(shí)體,或者說是網(wǎng)絡(luò)上的一個具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務(wù),就是一個具體的實(shí)在。

②統(tǒng)一接口

RESTful 架構(gòu)風(fēng)格規(guī)定,數(shù)據(jù)的元操作,即 CRUD(Create,Read,Update 和 Delete,即數(shù)據(jù)的增刪查改)操作,分別對應(yīng)于 HTTP 方法:GET 用來獲取資源,POST 用來新建資源(也可以用于更新資源),PUT 用來更新資源,DELETE 用來刪除資源,這樣就統(tǒng)一了數(shù)據(jù)操作的接口,僅通過 HTTP 方法,就可以完成對數(shù)據(jù)的所有增刪查改工作。

③URL

可以用一個 URI(統(tǒng)一資源定位符)指向資源,即每個 URI 都對應(yīng)一個特定的資源。

要獲取這個資源,訪問它的 URI 就可以,因此 URI 就成了每一個資源的地址或識別符。

④無狀態(tài)

所謂無狀態(tài)的,即所有的資源,都可以通過 URI 定位,而且這個定位與其他資源無關(guān),也不會因?yàn)槠渌Y源的變化而改變。有狀態(tài)和無狀態(tài)的區(qū)別,舉個簡單的例子說明一下。

如查詢員工的工資,如果查詢工資是需要登錄系統(tǒng),進(jìn)入查詢工資的頁面,執(zhí)行相關(guān)操作后,獲取工資的多少,則這種情況是有狀態(tài)的。

因?yàn)椴樵児べY的每一步操作都依賴于前一步操作,只要前置操作不成功,后續(xù)操作就無法執(zhí)行。

如果輸入一個 URI 即可得到指定員工的工資,則這種情況是無狀態(tài)的,因?yàn)楂@取工資不依賴于其他資源或狀態(tài)。

且這種情況下,員工工資是一個資源,由一個 URI 與之對應(yīng),可以通過 HTTP 中的 GET 方法得到資源,這是典型的 RESTful 風(fēng)格。

RPC 和 Restful API 對比

面對對象不同:

  • RPC 更側(cè)重于動作。
  • REST 的主體是資源。

RESTful 是面向資源的設(shè)計架構(gòu),但在系統(tǒng)中有很多對象不能抽象成資源,比如登錄,修改密碼等而 RPC 可以通過動作去操作資源。所以在操作的全面性上 RPC 大于 RESTful。

傳輸效率:

  • RPC 效率更高。RPC,使用自定義的 TCP 協(xié)議,可以讓請求報文體積更小,或者使用 HTTP2 協(xié)議,也可以很好的減少報文的體積,提高傳輸效率。

復(fù)雜度:

  • RPC 實(shí)現(xiàn)復(fù)雜,流程繁瑣。
  • REST 調(diào)用及測試都很方便。

RPC 實(shí)現(xiàn)(參見***節(jié))需要實(shí)現(xiàn)編碼,序列化,網(wǎng)絡(luò)傳輸?shù)取6?RESTful 不要關(guān)注這些,RESTful 實(shí)現(xiàn)更簡單。

靈活性:

  • HTTP 相對更規(guī)范,更標(biāo)準(zhǔn),更通用,無論哪種語言都支持 HTTP 協(xié)議。
  • RPC 可以實(shí)現(xiàn)跨語言調(diào)用,但整體靈活性不如 RESTful。

總結(jié)

RPC 主要用于公司內(nèi)部的服務(wù)調(diào)用,性能消耗低,傳輸效率高,實(shí)現(xiàn)復(fù)雜。

HTTP 主要用于對外的異構(gòu)環(huán)境,瀏覽器接口調(diào)用,App 接口調(diào)用,第三方接口調(diào)用等。

RPC 使用場景(大型的網(wǎng)站,內(nèi)部子系統(tǒng)較多、接口非常多的情況下適合使用 RPC):

  • 長鏈接。不必每次通信都要像 HTTP 一樣去 3 次握手,減少了網(wǎng)絡(luò)開銷。
  • 注冊發(fā)布機(jī)制。RPC 框架一般都有注冊中心,有豐富的監(jiān)控管理;發(fā)布、下線接口、動態(tài)擴(kuò)展等,對調(diào)用方來說是無感知、統(tǒng)一化的操作。
  • 安全性,沒有暴露資源操作。
  • 微服務(wù)支持。就是最近流行的服務(wù)化架構(gòu)、服務(wù)化治理,RPC 框架是一個強(qiáng)力的支撐。

【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請注明原文作者和出處為51CTO.com】

 

責(zé)任編輯:武曉燕 來源: 51CTO技術(shù)棧
相關(guān)推薦

2021-02-01 09:04:42

Python 項(xiàng)目distutils

2021-04-12 07:36:15

Scrapy爬蟲框架

2021-06-13 12:03:46

SaaS軟件即服務(wù)

2022-03-27 20:32:28

Knative容器事件模型

2021-10-09 00:02:04

DevOps敏捷開發(fā)

2020-03-09 09:13:40

HTTPSTCP網(wǎng)絡(luò)協(xié)議

2021-03-25 11:24:25

爬蟲技術(shù)開發(fā)

2021-10-17 20:38:30

微服務(wù)內(nèi)存組件

2021-12-03 18:25:56

數(shù)據(jù)指標(biāo)本質(zhì)

2022-04-27 18:25:02

數(shù)據(jù)采集維度

2021-10-12 18:31:40

流量運(yùn)營前端

2020-11-03 07:04:39

云計算公有云私有云

2021-09-13 08:41:52

職場互聯(lián)網(wǎng)自閉

2021-06-29 11:21:41

數(shù)據(jù)安全網(wǎng)絡(luò)安全黑客

2020-11-30 08:34:44

大數(shù)據(jù)數(shù)據(jù)分析技術(shù)

2022-04-12 18:29:41

元數(shù)據(jù)系統(tǒng)架構(gòu)

2022-04-22 11:26:55

數(shù)據(jù)管理架構(gòu)

2021-03-03 21:31:24

量化投資利潤

2021-02-14 00:21:37

區(qū)塊鏈數(shù)字貨幣金融

2022-01-05 18:27:44

數(shù)據(jù)挖掘工具
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

黄色手机在线视频| 亚洲a∨一区二区三区| 亚洲天堂日韩av| 国产欧美日韩在线观看视频| 8x8x8国产精品| 免费一级特黄特色毛片久久看| 欧美少妇另类| 国产美女娇喘av呻吟久久| 91禁国产网站| 中文字幕在线观看2018| 亚洲精品国模| 日韩美女天天操| 青青青在线视频免费观看| 色呦呦网站在线观看| 国产欧美日韩视频在线观看| 国产精品一区二区三区在线| 中文字幕av无码一区二区三区| 欧美日韩在线大尺度| 中文字幕日韩专区| 在线免费观看a级片| 亚洲综合视频| 欧美午夜精品久久久久久超碰| 精品一区二区三区无码视频| 91美女视频在线| 91麻豆精品在线观看| 91视频网页| 一级黄色片视频| 老妇喷水一区二区三区| 久久久噜噜噜久久中文字免| 国产高清视频免费在线观看| 亚洲精品国产精品粉嫩| 精品国产污污免费网站入口 | 黄色av片三级三级三级免费看| 日韩视频一区二区三区四区| 欧美日韩aaa| 日本新janpanese乱熟| 国产乱码精品一区二三赶尸艳谈| 18涩涩午夜精品.www| 视频一区视频二区视频| 欧美色18zzzzxxxxx| 99精品国产91久久久久久| 亚洲综合第一页| 国产毛片久久久久| 免费国产亚洲视频| 青青草原成人在线视频| 亚洲 欧美 视频| 激情综合中文娱乐网| 欧美另类极品videosbest最新版本 | 日韩精品一区在线视频| 免费电影网站在线视频观看福利| 亚洲欧美电影一区二区| 正在播放久久| 午夜伦理在线| 国产精品久久久久久久久免费相片| 欧美裸体网站| 黄色视屏网站在线免费观看| 久久久国产午夜精品| 欧美一区二区三区四区夜夜大片 | 欧美日韩高清在线观看| 久久r这里只有精品| 正在播放日韩欧美一页| 欧美猛少妇色xxxxx| 青青草国产在线观看| 欧美先锋影音| 久久久久久国产精品| 亚洲视频免费播放| 久久国产66| 国产精品一区二区久久久久| 888奇米影视| 国产麻豆欧美日韩一区| 国产精品一区二区欧美黑人喷潮水| 少妇高潮一区二区三区99小说 | 日韩一区二区免费高清| 免费在线观看日韩av| 开心激情综合| 亚洲日韩欧美视频一区| 久久精品国产亚洲AV成人婷婷| 欧美电影一二区| 欧美老少做受xxxx高潮| 日韩av黄色片| 日韩国产欧美在线观看| 亚洲tv在线观看| 日韩一级免费毛片| 国产精品无遮挡| 超碰97在线看| 欧美18—19sex性hd| 欧美高清视频一二三区 | 在线观看日本www| 1313精品午夜理伦电影| 日韩极品精品视频免费观看| 国产精品综合激情| 精品电影一区| 国产综合久久久久久| 黄色片网站免费在线观看| 国产亚洲精品资源在线26u| 日日噜噜噜夜夜爽爽| 99热99re6国产在线播放| 欧美亚洲一区二区在线| 无码人妻aⅴ一区二区三区玉蒲团| 台湾亚洲精品一区二区tv| 日韩中文第一页| 国产精品国产三级国产专区52| 麻豆精品精品国产自在97香蕉| 国产精品18毛片一区二区| 超碰在线影院| 欧美日韩午夜剧场| 国产福利精品一区二区三区| 日韩成人午夜| 欧美日本在线视频中文字字幕| 成人a v视频| av不卡免费电影| 青青在线免费视频| 九色成人搞黄网站| 日韩美女av在线| 久久久久免费看| 久久精品国产精品亚洲红杏 | 熟女人妻一区二区三区免费看| av一区二区高清| 4k岛国日韩精品**专区| 亚洲成人中文字幕在线| 中文字幕一区免费在线观看| 国产成人黄色片| 国产成人福利av| 久久久极品av| 国产又黄又粗又硬| 国产欧美精品一区aⅴ影院| wwwxxx黄色片| 亚洲精品国模| 欧美在线激情视频| 污污网站免费在线观看| 一区二区三区在线观看网站| 男女视频在线观看网站| 久久亚洲国产| 成人激情视频在线播放| 国产福利小视频在线观看| 欧美日韩美女视频| 日韩av一二区| 亚洲另类视频| 国产一区福利视频| 高清视频在线观看三级| 亚洲第一在线视频| 亚欧洲精品在线视频| 国产成人精品影院| 日韩精品一区二区免费| 国产精品极品| 97视频在线免费观看| 亚洲欧美色视频| 欧美日韩在线视频一区二区| 性欧美成人播放77777| 久久婷婷影院| 天堂社区 天堂综合网 天堂资源最新版| 国产免费不卡| 中文字幕日韩专区| 国产又粗又黄又爽的视频| 一区视频在线播放| 尤物网站在线看| 欧美日一区二区在线观看| a级国产乱理论片在线观看99| 久久www人成免费看片中文| 亚洲成人网在线观看| 亚洲免费激情视频| 国产喂奶挤奶一区二区三区| 91最新在线观看| 91久久高清国语自产拍| 亚洲va男人天堂| 人人超在线公开视频| 亚洲国内高清视频| 人人妻人人爽人人澡人人精品 | 午夜啪啪免费视频| 欧美a级大片在线| 久久男人av资源网站| 免费人成黄页在线观看忧物| 欧美日韩视频在线观看一区二区三区| 亚洲 欧美 国产 另类| 国产高清成人在线| 日韩在线视频在线观看| 日产精品一区二区| 成人9ⅰ免费影视网站| 中文不卡1区2区3区| 在线午夜精品自拍| 亚洲黄色a级片| 色综合天天综合网国产成人综合天 | 一区在线中文字幕| 中文字幕a在线观看| 青青草成人在线观看| av在线com| 日韩成人激情| 国产私拍一区| 久久国内精品| 性欧美长视频免费观看不卡| aⅴ在线视频男人的天堂| 欧美mv日韩mv亚洲| 国产字幕在线观看| 亚洲国产精品综合小说图片区| 久久精品—区二区三区舞蹈| 国产乱色国产精品免费视频| 一本大道熟女人妻中文字幕在线 | 丰满饥渴老女人hd| 久久青草久久| 91传媒免费视频| 国产一区99| 国产精品一区二区三区精品| 欧美成人高清视频在线观看| 97免费视频在线| 中文字幕中文字幕在线十八区| 国产亚洲精品久久久久久777| 成人久久久精品国产乱码一区二区 | 亚洲综合免费观看高清完整版| 成都免费高清电影| 成人午夜视频在线观看| 日韩va在线观看| 玖玖玖国产精品| 男女超爽视频免费播放| 综合日韩在线| 一区二区在线中文字幕电影视频| 西野翔中文久久精品字幕| 91黄在线观看| 四虎精品在线观看| 国产精品毛片a∨一区二区三区|国| segui88久久综合9999| 欧美xxxx做受欧美.88| 成人在线播放视频| 亚洲图片欧美午夜| 免费看男男www网站入口在线| 亚洲第一区在线| 亚洲第一视频在线| 日韩午夜小视频| 国产免费久久久| 欧美美女黄视频| 亚洲无码精品在线播放| 在线精品观看国产| 狠狠人妻久久久久久综合| 欧美日韩在线影院| 青青操免费在线视频| 亚洲一区二区三区四区在线免费观看 | 亚洲性视频h| 欧美交换配乱吟粗大25p| 天天操夜夜操国产精品| 在线成人性视频| 国产精品97| 欧美h视频在线观看| 天天影视欧美综合在线观看| 亚洲一区三区电影在线观看| 区一区二视频| 色呦呦网站入口| 亚洲国产精品久久久天堂 | 蜜桃av噜噜一区二区三区| 欧美美女在线直播| 欧美一级日本a级v片| 欧美天天综合| 亚洲人一区二区| 91超碰国产精品| 成年丰满熟妇午夜免费视频| 国产综合久久| 欧美丰满熟妇bbbbbb百度| 男女精品网站| 久久午夜夜伦鲁鲁一区二区| 蜜臀av性久久久久蜜臀av麻豆| 污网站免费在线| 国产精品一色哟哟哟| 无码人妻一区二区三区免费n鬼沢| 成人免费毛片嘿嘿连载视频| 亚洲av无码一区二区三区观看| 91美女视频网站| 天美传媒免费在线观看| 亚洲欧美一区二区不卡| 国产午夜小视频| 日韩欧美亚洲范冰冰与中字| 中文字幕在线日亚洲9| 日韩一级免费观看| 五月婷婷免费视频| 正在播放欧美视频| 麻豆福利在线观看| 欧美夜福利tv在线| 四虎影视精品永久在线观看| av成人免费观看| 亚洲区小说区| 先锋影音男人资源| 亚洲欧美不卡| 尤物网站在线看| 91在线免费播放| 精品国产国产综合精品| 亚洲h精品动漫在线观看| 欧美亚洲另类小说| 欧美大片在线观看| 韩日视频在线| 欧美激情二区三区| 桃子视频成人app| 5566中文字幕一区二区| 国产精品一区二区三区av麻| av中文字幕av| 日韩不卡手机在线v区| 日本少妇xxxx软件| 欧美高清在线视频| 国产精品不卡av| 337p亚洲精品色噜噜噜| 日本午夜在线视频| 欧美成人小视频| 日本肉肉一区| 精品国产免费一区二区三区| 99久久夜色精品国产亚洲96| 成人免费在线小视频| 国产精品99久久久久久久vr| 美女洗澡无遮挡| 亚洲成人福利片| 国产熟女一区二区丰满| 国产亚洲精品久久久久久牛牛 | 红桃视频成人在线观看| 国产露脸国语对白在线| 亚洲欧美中文在线视频| 天堂亚洲精品| 成人www视频在线观看| 欧美猛男男男激情videos| 18黄暴禁片在线观看| 韩国视频一区二区| 性少妇xx生活| 欧美亚洲综合久久| 激情在线视频| 欧美一二三视频| 久久精品国产亚洲5555| 黄色网址在线免费看| 美女一区二区三区| 国产黄色大片免费看| 欧美性黄网官网| 午夜在线视频观看| 欧美福利在线观看| 看亚洲a级一级毛片| 制服诱惑一区| 久久精品72免费观看| 国产欧美一区二区三区在线观看视频| 欧美日韩国产中文精品字幕自在自线| 后进极品白嫩翘臀在线视频| 欧美大片在线看| 欧美特黄不卡| 日韩人妻一区二区三区蜜桃视频| 久久99久久99| 永久av免费网站| 欧美巨大另类极品videosbest | 91免费看网站| 欧美特黄a级高清免费大片a级| 日本一本在线视频| 亚洲同性gay激情无套| 国产按摩一区二区三区| 欧美久久久精品| 91成人噜噜噜在线播放| 18禁裸男晨勃露j毛免费观看| 粉嫩aⅴ一区二区三区四区 | 国产又粗又硬视频| 欧美性色黄大片| 一级毛片视频在线观看| 国产日韩欧美中文在线播放| 欧美国产一级| 可以看的av网址| 午夜成人免费电影| 日色在线视频| 国产精品久久久久aaaa九色| 欧美aaaa视频| 九九九久久久久久久| 亚洲韩国精品一区| 日本福利片在线| 国产精品视频公开费视频| 99国产精品一区二区| 午夜性福利视频| 欧美日韩加勒比精品一区| 可以免费看污视频的网站在线| 国产精品成熟老女人| 久久久久国产| 这里只有精品在线观看视频| 欧美色道久久88综合亚洲精品| 国产精品二线| 亚洲在线第一页| 99亚洲一区二区| 成人性生活免费看| 欧美又粗又大又爽| a天堂中文在线官网在线| 国产一区高清视频| 久久精品久久综合| 亚洲国产精品午夜在线观看| 国产午夜精品免费一区二区三区| 自拍偷拍亚洲| 黄色av网址在线播放| 中文字幕精品三区| 少妇高潮一区二区三区69| 国产噜噜噜噜久久久久久久久| 精品91在线| 亚洲女人久久久| 日韩av最新在线| 精品国产一级| 成年人在线看片| 亚洲一级二级三级在线免费观看| 北条麻妃在线| 国产日韩精品久久| 美女精品自拍一二三四| 日本亚洲色大成网站www久久| 日韩中文字幕国产| 欧美自拍一区| 麻豆精品国产传媒| 欧美网站大全在线观看| 色是在线视频| av影院在线播放|