淺談 RPC

本文來自於Dubbo官網: 淺談 RPC,轉載請保留連接 ;)

近幾年隨着微服務化項目的崛起,逐漸成爲許多公司中大型分佈式系統架構的主流方式,而今天所說的 RPC 在這其中扮演着相當重要的角色。隨着這段日子公司項目微服務化的演進,發如今平常開發中都在隱式或顯式的使用 RPC,一些剛剛接觸 RPC 的小夥伴會感受無所適從,而一些入行多年的老手雖然使用 RPC 經驗豐富,但有些對其原理也只知其一;不知其二,缺少對原理的深刻理解,每每也會形成開發中的一些誤用。html

什麼是RPC?

RPC(Remote Procedure Call)—遠程過程調用,它是一種經過網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議。也就是說兩臺服務器A,B,一個應用部署在A服務器上,想要調用B服務器上應用提供的方法,因爲不在一個內存空間,不能直接調用,須要經過網絡來表達調用的語義和傳達調用的數據。程序員

RPC協議假定某些傳輸協議的存在,如TCP或UDP,爲通訊程序之間攜帶信息數據。在OSI網絡通訊模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分佈式多程序在內的應用程序更加容易。如今業界有不少開源的優秀 RPC 框架,例如 Spring Cloud、Dubbo、Thrift 等。算法

RPC 起源

RPC 這個概念術語在上世紀 80 年代由 Bruce Jay Nelson 提出。這裏咱們追溯下當初開發 RPC 的原動機是什麼?在 Nelson 的論文 "Implementing Remote Procedure Calls" 中他提到了幾點:apache

  • 簡單:RPC 概念的語義十分清晰和簡單,這樣創建分佈式計算就更容易。
  • 高效:過程調用看起來十分簡單並且高效。
  • 通用:在單機計算中過程每每是不一樣算法部分間最重要的通訊機制。

通俗一點說,就是通常程序員對於本地的過程調用很熟悉,那麼咱們把 RPC 做成和本地調用徹底相似,那麼就更容易被接受,使用起來毫無障礙。Nelson 的論文發表於 30 年前,其觀點今天看來確實高瞻遠矚,今天咱們使用的 RPC 框架基本就是按這個目標來實現的。服務器

RPC 結構

Nelson 的論文中指出實現 RPC 的程序包括 5 個部分:網絡

  1. User
  2. User-stub
  3. RPCRuntime
  4. Server-stub
  5. Server

圖片描述

這裏 user 就是 client 端,當 user 想發起一個遠程調用時,它實際是經過本地調用 user-stub。user-stub 負責將調用的接口、方法和參數經過約定的協議規範進行編碼並經過本地的 RPCRuntime 實例傳輸到遠端的實例。遠端 RPCRuntime 實例收到請求後交給 server-stub 進行解碼後發起本地端調用,調用結果再返回給 user 端。架構

以上是粗粒度的 RPC 實現概念結構,接下來咱們進一步細化它應該由哪些組件構成,以下圖所示。負載均衡

圖片描述

RPC 服務方經過 RpcServer 去導出(export)遠程接口方法,而客戶方經過 RpcClient 去引入(import)遠程接口方法。客戶方像調用本地方法同樣去調用遠程接口方法,RPC 框架提供接口的代理實現,實際的調用將委託給代理RpcProxy 。代理封裝調用信息並將調用轉交給RpcInvoker 去實際執行。在客戶端的RpcInvoker 經過鏈接器RpcConnector 去維持與服務端的通道RpcChannel,並使用RpcProtocol 執行協議編碼(encode)並將編碼後的請求消息經過通道發送給服務方。框架

RPC 服務端接收器 RpcAcceptor 接收客戶端的調用請求,一樣使用RpcProtocol 執行協議解碼(decode)。解碼後的調用信息傳遞給RpcProcessor 去控制處理調用過程,最後再委託調用給RpcInvoker 去實際執行並返回調用結果。以下是各個部分的詳細職責:異步

1. RpcServer  

   負責導出(export)遠程接口  

2. RpcClient  

   負責導入(import)遠程接口的代理實現  

3. RpcProxy  

   遠程接口的代理實現  

4. RpcInvoker  

   客戶方實現:負責編碼調用信息和發送調用請求到服務方並等待調用結果返回  

   服務方實現:負責調用服務端接口的具體實現並返回調用結果  

5. RpcProtocol  

   負責協議編/解碼  

6. RpcConnector  

   負責維持客戶方和服務方的鏈接通道和發送數據到服務方  

7. RpcAcceptor  

   負責接收客戶方請求並返回請求結果  

8. RpcProcessor  

   負責在服務方控制調用過程,包括管理調用線程池、超時時間等  

9. RpcChannel  

   數據傳輸通道

RPC 工做原理

RPC的設計由Client,Client stub,Network ,Server stub,Server構成。 其中Client就是用來調用服務的,Cient stub是用來把調用的方法和參數序列化的(由於要在網絡中傳輸,必需要把對象轉變成字節),Network用來傳輸這些信息到Server stub, Server stub用來把這些信息反序列化的,Server就是服務的提供者,最終調用的就是Server提供的方法。

圖片描述

  1. Client像調用本地服務似的調用遠程服務;
  2. Client stub接收到調用後,將方法、參數序列化
  3. 客戶端經過sockets將消息發送到服務端
  4. Server stub 收到消息後進行解碼(將消息對象反序列化)
  5. Server stub 根據解碼結果調用本地的服務
  6. 本地服務執行(對於服務端來講是本地執行)並將結果返回給Server stub
  7. Server stub將返回結果打包成消息(將結果消息對象序列化)
  8. 服務端經過sockets將消息發送到客戶端
  9. Client stub接收到結果消息,並進行解碼(將結果消息發序列化)
  10. 客戶端獲得最終結果。

RPC 調用分如下兩種:

  1. 同步調用:客戶方等待調用執行完成並返回結果。
  2. 異步調用:客戶方調用後不用等待執行結果返回,但依然能夠經過回調通知等方式獲取返回結果。若客戶方不關心調用返回結果,則變成單向異步調用,單向調用不用返回結果。

異步和同步的區分在因而否等待服務端執行完成並返回結果。

RPC 能幹什麼?

RPC 的主要功能目標是讓構建分佈式計算(應用)更容易,在提供強大的遠程調用能力時不損失本地調用的語義簡潔性。爲實現該目標,RPC 框架需提供一種透明調用機制,讓使用者沒必要顯式的區分本地調用和遠程調用,在以前給出的一種實現結構,基於 stub 的結構來實現。下面咱們將具體細化 stub 結構的實現。

  • 能夠作到分佈式,現代化的微服務
  • 部署靈活
  • 解耦服務
  • 擴展性強

RPC的目的是讓你在本地調用遠程的方法,而對你來講這個調用是透明的,你並不知道這個調用的方法是部署哪裏。經過RPC能解耦服務,這纔是使用RPC的真正目的。

總結

這篇文章介紹了 RPC 的一些基本原理,相信到這裏您已經對 RPC 有了必定理解。其實發現實現一個 RPC 不算難,難的是實現一個高性能高可靠的RPC框架。好比,既然是分佈式了,那麼一個服務可能有多個實例,你在調用時,要如何獲取這些實例的地址呢?這時候就須要一個服務註冊中心,好比在Dubbo中,就可使用Zookeeper做爲註冊中心,在調用時,從Zookeeper獲取服務的實例列表,再從中選擇一個進行調用。那麼選哪一個調用好呢?這時候就須要負載均衡了,因而你又得考慮如何實現複雜均衡,好比Dubbo就提供了好幾種負載均衡策略。因此請繼續關注個人另外兩篇文章RPC與服務化的關係註冊中心,配置中心, 服務發現淺談,相信會幫助對RPC設計和實現有更多的理解。

相關文章
相關標籤/搜索