RPC與RPC框架

RPC即 Remote Procedure Call ,遠程過程調用,一種通信概念,編程模型概念

通俗講,兩臺服務器A,B,一個應用部署在A服務器上,想要調用B服務器上應用提供的函數/方法,由於不在一個內存空間,不能直接調用,需要通過網絡來表達調用的語義和傳達調用的數據。

爲什麼要遠程調用

無法在一個進程內,甚至一個計算機內通過本地調用的方式完成的需求,比如不同的系統間的通訊,甚至不同的組織間的通訊。由於計算能力需要橫向擴展,需要在多臺機器組成的集羣上部署應用。又可能需要調用其它服務器服務,或者本地服務器無法完成數據計算,需要調用集羣等,算力要擴展,分佈式在發展,計算機要通信,RPC誕生。

更多的,很多服務都可以抽出來以責任鏈模式進行執行:

一個請求應答網絡交互通常包含兩條鏈,一條鏈(Upstream)是從傳輸層,經過一系列步驟,如身份認證,解密,日誌,流控,最後到達業務層,一條鏈(DownStream)是業務層返回後,又經過一系列步驟,如加密等,又回到傳輸層。 現代業務需要RPC。

分佈式服務中,可以用RPC,但是不是也可以通過Restful API進行調用呢,思想很接近,只不過Restful API基於http/https,報文傳輸效率不高,同時需要顯示發起報文,如何向調用本地方法一樣調用遠程方法?用RPC

RPC專爲遠程過程調用而生,基於底層如TCP,自定義報文傳輸,屏蔽底層細節,核心就是序列化/反序列化+網絡通信,這就是很多RPC框架要解決的問題和解決的思路,比如阿里的Dubbo。RPC 是構建分佈式應用的理論基礎

RPC要解決的兩個主要問題:

1. 解決分佈式系統中,服務之間的調用問題。

2. 遠程調用時,要能夠像本地調用一樣方便,讓調用者感知不到遠程調用的邏輯。

RPC過程

首先,要通過在客戶端和服務器之間建立TCP連接(也可以使用其它協議如UDP等,只要能完成數據傳輸就好),遠程過程調用的所有交換的數據都在這個連接裏傳輸。RPC協議自定義報文。

第二,解決尋址的問題,也就是說,A服務器上的應用怎麼告訴底層的RPC框架,如何連接到B服務器(如主機或IP地址)以及特定的端口,方法的名稱名稱是什麼,這樣才能完成調用,即維護一個Map,使用Call-ID與函數指針映射完成調用映射。

第三,數據序列化,方法的參數需要通過底層的網絡協議如TCP傳遞到B服務器,由於網絡協議是基於二進制的,內存中的參數的值要序列化成二進制的形式,也就是序列化(Serialize),通過尋址和傳輸將序列化的二進制發送給B服務器。

第四,服務器數據反序列化,B服務器收到請求後,需要對參數進行反序列化(序列化的逆操作),恢復爲內存中的表達方式,然後找到對應的方法(尋址的一部分)進行本地調用,然後得到返回值。

第五,返回值還要發送回服務器A上的應用,也要經過序列化的方式發送,服務器A接到後,再反序列化,恢復爲內存中的表達方式,交給A服務器上的應用

img

RPC框架好處

http接口是在接口不多、系統與系統交互較少的情況下,解決信息孤島初期常使用的一種通信手段;

優點就是簡單、直接、開發方便。

如果是一個大型的網站,內部子系統較多、接口非常多的情況下,RPC框架的好處就顯示出來了:

RPC框架一般都有註冊中心,有豐富的監控管理;發佈、下線接口、動態擴展等,對調用方來說是無感知、統一化的操作。

論複雜度,dubbo/hessian用起來超級簡單:

調用簡單,真正提供了類似於調用本地方法一樣調用接口的功能 。

參數返回值簡單明瞭 參數和返回值都是直接定義在jar包裏的,不需要二次解析。

輕量,沒有多餘的信息。

便於管理,基於dubbo的註冊中心。

RPC能解耦服務

RPC:遠程過程調用。RPC的核心並不在於使用什麼協議。RPC的目的是讓你在本地調用遠程的方法,而對你來說這個調用是透明的,你並不知道這個調用的方法是部署哪裏。

通過RPC能解耦服務,這纔是使用RPC的真正目的。RPC的原理主要用到了動態代理模式。

RPC框架要解決的問題

RPC原理簡單:數據序列化/反序列化+網絡通信(如基於TCP的Socket,用Netty),高可用的RPC需要考慮很多

在分佈式中,既然是分佈式了,那麼一個服務可能有多個實例,你在調用時,要如何獲取這些實例的地址呢?

這時候就需要一個服務註冊中心,比如在Dubbo裏頭,就可以使用Zookeeper作爲註冊中心,在調用時,從Zookeeper獲取服務的實例列表,再從中選擇一個進行調用。

那麼選哪個調用好呢?這時候就需要負載均衡了,於是你又得考慮如何實現負載均衡,比如Dubbo就提供了好幾種負載均衡策略。

這還沒完,總不能每次調用時都去註冊中心查詢實例列表吧,這樣效率多低呀,於是又有了緩存,有了緩存,就要考慮緩存的更新問題,blablabla……

你以爲就這樣結束了,沒呢,還有這些:

  • 客戶端總不能每次調用完都乾等着服務端返回數據吧,於是就要支持異步調用;
  • 服務端的接口修改了,老的接口還有人在用,怎麼辦?總不能讓他們都改了吧?這就需要版本控制了;
  • 服務端總不能每次接到請求都馬上啓動一個線程去處理吧?於是就需要線程池;
  • 服務端關閉時,還沒處理完的請求怎麼辦?是直接結束呢,還是等全部請求處理完再關閉呢?
  • ……

如此種種,都是一個優秀的RPC框架需要考慮的問題。

RPC簡單實現與問題: https://zhuanlan.zhihu.com/p/36528189

參考:

知乎搜索:RPC

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章