高併發架構系列:RPC通信機制你瞭解嗎

前言

在分佈式系統中,因爲每個服務的邊界都很小,很有可能調用別的服務提供的方法。這就出現了服務A調用服務B中方法的需求,即遠程過程調用。

要想讓服務A調用服務B中的方法,最先想到的就是通過HTTP請求實現。是的,這是很常見的,例如服務B暴露Restful接口,然後讓服務A調用它的接口。基於Restful的調用方式因爲可讀性好(服務B暴露出的是Restful接口,可讀性當然好)而且HTTP請求可以通過各種防火牆,因此非常不錯。

然而,基於Restful的遠程過程調用有着明顯的缺點,主要是效率低、封裝調用複雜。當存在大量的服務間調用時,這些缺點變得更爲突出。

服務A調用服務B的過程是應用間的內部過程,犧牲可讀性提升效率、易用性是可取的。基於這種思路,基於TCP模式RPC產生了。通常,RPC要求在調用方中放置被調用的方法的接口。調用方只要調用了這些接口,就相當於調用了被調用方的實際方法,十分易用。於是,調用方可以像調用內部接口一樣調用遠程的方法,而不用封裝參數名和參數值等操作。

RPC簡介

RCP即遠程過程調用,它是一個計算機通信協議,允許調用者像調用本地服務一樣調用遠程服務,下面這張圖是典型的RPC調用圖:

RPC是怎麼實現遠程過程調用的呢?

服務端將對外接口以jar包的形式發佈,客戶端引用服務端發佈的jar包。n多個接口調用過程中,每個接口如何找到對應的實現類呢,這時候JDK動態代理就派上用場了,客戶端發送接口調用請求,動態代理接收到調用後,將進行一系列操作實現遠程接口的調用。整過調用過程將進行一下幾個步驟:

客戶端:

①自定義請求協議。protocol是client與server交互的語法。Http定義了http請求協議規則,Dubbo定義了Dubbo協議請求規則,我們也可以自定義請求協議。客戶端按照協議組裝數據,併發送至服務端;服務端按照協議解析客戶端請求數據,執行客戶端請求接口方法,把結果按照協議組裝發送至客戶段端;最後客戶端按照協議解析服務端的返回結果。

將調用方法的入參進行序列化。當A機器上的應用發起一個RPC調用時,調用方法和其入參等信息需要通過底層的網絡協議如TCP傳輸到B機器,由於網絡協議是基於二進制的,所有我們傳輸的參數數據都需要先進行序列化(Serialize)或者編組(marshal)成二進制的形式才能在網絡中進行傳輸。然後通過尋址操作和網絡傳輸將序列化或者編組之後的二進制數據發送給B機器。

③識別具體要調用的遠程方法的IP、端口。A服務器上的應用怎麼告訴底層的RPC框架,如何連接到B服務器(如主機或IP地址)以及特定的端口,方法的名稱名稱是什麼。通常情況下我們需要提供B機器(主機名或IP地址)以及特定的端口,然後指定調用的方法或者函數的名稱以及入參出參等信息,這樣才能完成服務的一個調用。

é«å¹¶åæ¶æç³»åï¼RPCæ¡æ¶çå®ç°åçï¼è°ç¨å¨è¿ç¨ï¼åRPCæ¶æç»ä»¶

可靠的尋址方式(主要是提供服務的發現)是RPC的實現基石,比如可以採用redis或者zookeeper來註冊服務等等。

④建立通信。首先要解決通訊的問題:即A機器想要調用B機器,首先得建立起通信連接。

主要是通過在客戶端和服務器之間建立TCP連接,遠程過程調用的所有交換的數據都在這個連接裏傳輸。連接可以是按需連接,調用結束後就斷掉,也可以是長連接,多個遠程過程調用共享同一個連接。

服務端:

反序列化

當B機器接收到A機器的應用發來的請求之後,又需要對接收到的參數等信息進行反序列化操作(序列化的逆操作),即將二進制信息恢復爲內存中的表達方式,然後再找到對應的方法(尋址的一部分)進行本地調用。

②本地接口調用,請求處理。

③結果返回。服務端對返回結果進行序列化,再經過網絡傳輸將二進制數據發送回A機器,而當A機器接收到這些返回值之後,則再次進行反序列化操作,恢復爲內存中的表達方式,最後再交給A機器上的應用進行相關處理(一般是業務邏輯處理操作)。

RPC調用過程圖解:

é«å¹¶åæ¶æç³»åï¼RPCæ¡æ¶çå®ç°åçï¼è°ç¨å¨è¿ç¨ï¼åRPCæ¶æç»ä»¶

 

1、服務消費者(client客戶端)通過本地調用的方式調用服務

2、客戶端存根(client stub)接收到調用請求後負責將方法、入參等信息序列化(組裝)成能夠進行網絡傳輸的消息體

3、客戶端存根(client stub)找到遠程的服務地址,並且將消息通過網絡發送給服務端

4、服務端存根(server stub)收到消息後進行解碼(反序列化操作)

5、服務端存根(server stub)根據解碼結果調用本地的服務進行相關處理

6、本地服務執行具體業務邏輯並將處理結果返回給服務端存根(server stub)

7、服務端存根(server stub)將返回結果重新打包成消息(序列化)並通過網絡發送至消費方

8、客戶端存根(client stub)接收到消息,並進行解碼(反序列化)

9、服務消費方得到最終結果

Protocol

 protocol是client與server交互的語法。Http定義了http請求協議規則,Dubbo定義了Dubbo協議請求規則,我們也可以自定義請求協議。客戶端按照協議組裝數據,併發送至服務端;服務端按照協議解析客戶端請求數據,執行客戶端請求接口方法,把結果按照協議組裝發送至客戶段端;最後客戶端按照協議解析服務端的返回結果

Serial

客戶端和服務端之間的通訊是基於TCP協議的,TCP傳輸的數據全都是byte流。如此,一個會話的處理流程爲:首先,dsf客戶端把請求數據(調用接口方法、參數)轉化(序列化)爲byte數組,發送到服務端;接着,服務端接收到byte數組,把byte數組反向轉化(反序列化)爲請求數據(調用接口方法、參數),根據請求數據執行具體的接口實現類的方法並得到執行結果,完了把結果轉化(序列化)爲byte數組,發送到客戶端;最後,客戶端接收到服務端發送的byte數組,把byte數組反向轉化(反序列化)爲執行結果。如下圖所示:

dubbo架構

dubbo是一個高性能高擴展性的rpc服務調用框架,它的rpc調用過程也遵循上面的流程,dubbo架構圖如下:

包含四個核心組件:

1)服務消費者,遠程服務的調用端;

2)服務提供者,提供遠程服務;

3)服務註冊中心,提供的服務發現、容災、降級等服務治理能力;

4)服務監控,監控和統計服務的健康程度。

理論上只需要有消費者和提供者就能實現遠程服務調用了,但在實際的生成環境中註冊中心的服務治理能力和監控組件的監控能力對一個健康的系統是不可或缺的。

 

文章參考:

https://baijiahao.baidu.com/s?id=1640952736297475769&wfr=spider&for=pc

https://www.toutiao.com/a6797580498257314307/

https://www.toutiao.com/a6631154767844344327/

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