當前位置:
首頁 > 最新 > 揭秘RPC框架-實現原理

揭秘RPC框架-實現原理

一、背景

在傳統的垂直應用架構領域,比較流行的有LAMP(Linux+Apache+Mysql+Php)+MVC架構(SSH,SSI),通常應用代碼會統一打成一個war包,部署在Tomcat等WEB容器中,不同的應用功能之間通過本地API進行調用,基本不存在跨進程的遠程服務調用, 他們適用於小規模應用場景,即所有功能部署在同一個進程中,用於前後台邏輯的分離。很明顯,垂直應用架構有如下幾個弊端:

1、開發維護成本高,部署效率低(全量編譯和部署)

2、團隊協作效率差,部分公共功能重複開發,代碼重複高

3、系統可靠性差,單點故障頻繁

4、維護和定製困難,業務代碼不好拆分

5、新功能上線周期變長,各模塊強耦合(公共API測試工作量大,回歸時間長,新特性無法獨立部署和交付,需要和老功能一起編譯打包測試)

當垂直應用越來越多,應用之間的跨進程交互不可避免,將核心和公共服務抽取出來,作為獨立的服務,提高業務復用,RCP架構應運而生,再結合服務治理形成面向服務架構(SOA),進行服務生命周期管理,服務發現自動註冊,服務降級,流量控制等。為進一步提高服務的可用性,將服務進行原子化拆分,獨立打包部署,通過這種微服務模式,深入敏捷開發、持續交互實踐,對業務侵入性降到了最低,擴容方便運維成本也大幅降低,深受互聯網公司青睞。

二、RPC簡介

RPC(Remote Procedure Call),一種進程間通信方式,允許像調用本地過程一樣調用遠程服務,可以有不同的實現方式,如RMI,HTTPInvoker等,它具有如下幾個特點:

1、遠程服務調用簡單、透明

2、跨進程調用通用化,單機調用到遠程調用

3、屏蔽底層數據傳輸方式(TCP/UDP)、序列化方式(xml/json/二進位)與網路通信(BIO/NIO)細節,客戶端只需要介面,而服務部署在遠程。

單純的RPC框架(如FaceBook開源的Thrift)並不是完整的分散式服務框架,可以理解為:RPC框架+服務自動註冊與發現+服務治理=分散式服務框架 。當然一個分散式服務架構遠不止如此,比較常見的功能包括「服務發布訂閱+服務路由+集群容錯+服務調用模式+多協議+序列化方式+統一配置+服務監控+服務安全+故障快速定位定界+服務發現+服務治理+服務降級+服務隔離+服務降級+服務心跳/重連+流量控制+超時控制+服務生命周期管理+心跳機制+服務多版本+負載均衡」等等。

三、RPC調用過程

一次RCP調用返回涉及到客戶端與服務端的往返通信,具體如下圖所示:

客戶端通過代理類封裝請求方法和參數,將請求序列化後發出網路請求,服務端接收客戶端請求,首先進行反序列化拿到客戶端的請求對象進行相關處理,發起本地調用,將調用結果進行序列化通過網路返回發往客戶端,客戶端對響應碼流進行反序列並將結果返回給客戶端,從而實現一次RPC握手。這也是我們後面實現一個簡單RPC示常式序的基本思路。在Client Stub進行客戶端請求參數的綁定並進行網路交互,在Server Stub進行參數的解綁映射發起本地調用並對結果封裝返回。其實業界諸多的分散式通信框架也是如此,只是它的每一步都考慮了更為完整的處理機制。

四、一個簡單的例子

通過上述對RPC過程的分析,我們已經知道要實現一個RCP模型,客戶端處理器(Client Stub)和服務端處理器(Server Stub)是關鍵。下面我們通過代碼來逐一剖析,即不依賴任何第三方類庫,實現一個簡單的RPC框架。

4.1 客戶端代碼

先定義一個介面EchoService:

public interface EchoService {

String echo(String ping);

int add(int a, int b);

}

4.2 服務端代碼

public class EchoServiceImpl implements EchoService {

@Override

public String echo(String ping) {

return ping != null ? ping + "--> i am ok" : "i am ok";

}

@Override

public int add(int a, int b) {

return a+b;

}

}

4.3 客戶端處理器

實現遠程服務的本地代理,通過jdk動態代理的攔截機制,將本地調用封裝成遠程服務調用,然後將結果進行封裝返回給本地客戶端。

public class RpcImporter{

分析:採用jdk動態代碼模式封裝客戶端發起網路請求,當代理對象調用真實目標對象的方法時,其會自動跳轉到代碼對象關聯的handler對象的invoke方法進行調用,Object returnValue = method.invoke(subject,args);

4.4 服務端處理器

public class RpcExporter {

}

4.5 客戶端調用代碼

public class RpcClientTest {

public static String HOST_NAME = "localhost";

public static int PORT = 8998;

4.6 執行結果

1、先啟動服務端,顯示

begin connect client...

2、然後啟動客戶端

客戶端輸出:

服務端輸出:

五、總結

RPC架構分為三部分:

(1)服務提供者(Provider),運行在伺服器端,提供服務介面定義與服務實現類。

(2)服務發布者(RPCExporter),運行在伺服器端,負責將本地服務發布成遠程服務,管理遠程服務,提供給服務消費者使用。

(3)本地服務代理(RPCImporter),運行在客戶端,通過遠程代理對象調用遠程服務。

最後分享一個分散式服務框架典型實例架構模型

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 技術之積累 的精彩文章:

揭秘RPC框架-核心組件

TAG:技術之積累 |