1. 程式人生 > >從零開始實現RPC框架

從零開始實現RPC框架

RPC概述 RPC(Remote Procedure Call)即遠端過程呼叫,允許一臺計算機呼叫另一臺計算機上的程式得到結果,而程式碼中不需要做額外的程式設計,就像在本地呼叫一樣。

現在網際網路應用的量級越來越大,單臺計算機的能力有限,需要藉助可擴充套件的計算機叢集來完成,分散式的應用可以藉助RPC來完成機器之間的呼叫。

RPC框架原理 在RPC框架中主要有三個角色:Provider、Consumer和Registry。如下圖所示: 

è¿éåå¾çæè¿° 節點角色說明:  * Server: 暴露服務的服務提供方。  * Client: 呼叫遠端服務的服務消費方。  * Registry: 服務註冊與發現的註冊中心。

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)服務消費方得到最終結果。

RPC框架的目標就是要2~8這些步驟都封裝起來,讓使用者對這些細節透明。

服務註冊&發現  è¿éåå¾çæè¿° 服務提供者啟動後主動向註冊中心註冊機器ip、port以及提供的服務列表;  服務消費者啟動時向註冊中心獲取服務提供方地址列表,可實現軟負載均衡和Failover;

使用到的技術 1、動態代理  生成 client stub和server stub需要用到 Java 動態代理技術 ,我們可以使用JDK原生的動態代理機制,可以使用一些開源位元組碼工具框架 如:CgLib、Javassist等。

2、序列化  為了能在網路上傳輸和接收 Java物件,我們需要對它進行 序列化和反序列化操作。  * 序列化:將Java物件轉換成byte[]的過程,也就是編碼的過程;  * 反序列化:將byte[]轉換成Java物件的過程;

可以使用Java原生的序列化機制,但是效率非常低,推薦使用一些開源的、成熟的序列化技術,例如:protobuf、Thrift、hessian、Kryo、Msgpack

關於序列化工具效能比較可以參考:jvm-serializers

3、NIO  當前很多RPC框架都直接基於netty這一IO通訊框架,比如阿里巴巴的HSF、dubbo,Hadoop Avro,推薦使用Netty 作為底層通訊框架。

4、服務註冊中心  可選技術:  * Redis  * Zookeeper  * Consul  * Etcd

程式設計實踐 本人基於 Netty4 + Zookeeper + protostuff + Spring 實現了一個簡單、高效的RPC框架Mango:https://github.com/TiFG/mango,歡迎大家fork/star。