分散式架構核心RPC原理
在應用的迭代演進過程中,隨著系統訪問量提高,業務複雜度提高,程式碼複雜度提高,應用逐漸從單體式架構向面向服務的分散式架構轉變。RPC(Remote Procedure Call Protocol遠端過程呼叫)是分散式架構的核心,按響應方式分如下兩種:
同步呼叫:客戶端呼叫服務方方法,等待直到服務方返回結果或者超時,再繼續自己的操作
非同步呼叫:客戶端把訊息傳送給中介軟體,不再等待服務端返回,直接繼續自己的操作。
同步呼叫的實現方式有WebService和RMI。Web Service提供的服務是基於web容器的,底層使用http協議,因而適合不同語言異構系統間的呼叫。RMI實際上是Java語言的RPC實現,允許方法返回 Java 物件以及基本資料型別,適合用於JAVA語言構建的不同系統間的呼叫。
非同步呼叫的JAVA實現版就是JMS(Java Message Service),目前開源的的JMS中介軟體有Apache社群的ActiveMQ和Kafka,另外有阿里的RocketMQ,昨天(2016年11月28日)看到的新聞阿里已經將此元件捐獻給Apache社群基金組織。
下面重點對RPC同步呼叫的原理進行探討。簡單來說一個RPC架構裡包含如下4個元件:
1、 客戶端(Client):服務呼叫方
2、 客戶端存根(Client Stub):存放服務端地址資訊,將客戶端的請求引數打包成網路訊息,再通過網路傳送給服務方
3、 服務端存根(Server Stub):接受客戶端傳送過來的訊息並解包,再呼叫本地服務
4、 服務端(Server):真正的服務提供者。
這4個元件呼叫時序圖如下:
1、 服務呼叫方(client)呼叫以本地呼叫方式呼叫服務;
2、 client stub接收到呼叫後負責將方法、引數等組裝成能夠進行網路傳輸的訊息體;在Java裡就是序列化的過程
3、 client stub找到服務地址,並將訊息通過網路傳送到服務端;
4、 server stub收到訊息後進行解碼,在Java裡就是反序列化的過程;
5、 server stub根據解碼結果呼叫本地的服務;
6、 本地服務執行處理邏輯;
7、 本地服務將結果返回給server stub;
8、 server stub將返回結果打包成訊息,Java裡的序列化;
9、 server stub將打包後的訊息通過網路併發送至消費方
10、 client stub接收到訊息,並進行解碼, Java裡的反序列化;
11、 服務呼叫方(client)得到最終結果。
RPC框架的目標就是把2-10步封裝起來,把呼叫、編碼/解碼的過程封裝起來,讓使用者像呼叫本地服務一樣的呼叫遠端服務。要做到對客戶端(呼叫方)透明化服務, RPC框架需要考慮解決如下問題:
1、 服務端提供的服務如何釋出,客戶端如何發現服務;
2、 如何對請求物件和返回結果進行序列化和反序列化;
3、 如何更高效進行網路通訊。
以上問題在一些開源的RPC框架裡都有比較好的解決,如阿里的Dubbo,Facebook的Thrift。有興趣的同學可以對這兩個框架進行深入學習研究。
RPC是每個分散式應用的必用之術,本文只是進行了一個粗略的描述,希望能對大家所有幫助,拋磚引玉,引起更多人對底層技術實現的興趣。