五分鐘快速掌握RPC原理及實現
隨著公司規模的不斷擴大,以及業務量的激增,單體應用逐步演化為服務/微服務的架構模式, 服務之間的呼叫大多采用rpc的方式呼叫,或者訊息佇列的方式進行解耦。幾乎每個大廠都會建立自己的rpc框架,或者基於知名的rpc框架進行改造因此今天我們來講講rpc吧。
RPC概述
RPC(Remote Procedure Call)即遠端過程呼叫,也就是說兩臺伺服器A,B,一個應用部署在A伺服器上,想要呼叫B伺服器上應用提供的函式/方法,由於不在一個記憶體空間,不能直接呼叫,需要通過網路來表達呼叫的語義和傳達呼叫的資料。
RPC框架原理
在RPC框架中主要有三個角色:Provider、Consumer和Registry。如下圖所示:
節點角色說明:
* Server: 暴露服務的服務提供方。
* Client: 呼叫遠端服務的服務消費方。
* Registry: 服務註冊與發現的註冊中心。
RPC呼叫流程
1.呼叫客戶端控制代碼;執行傳送引數
2.呼叫本地系統核心傳送網路訊息
3.訊息傳送到遠端主機
4.伺服器控制代碼得到訊息並取得引數
5.執行遠端過程
6.執行的過程將結果返回伺服器控制代碼
7.伺服器控制代碼返回結果,呼叫遠端系統核心
8.訊息傳回本地主機
9.客戶控制代碼由核心接收訊息
10.客戶接收控制代碼返回的資料
服務註冊&發現
服務提供者啟動後主動向註冊中心註冊機器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
JAVA中幾種常用的RPC框架介紹
Java中的RPC框架比較多,各有特色,廣泛使用的有RMI、Hessian、Dubbo等。
RPC還有一個特點就是能夠跨語言,本文只以JAVA語言裡的RPC為例。
RMI(遠端方法呼叫)
JAVA自帶的遠端方法呼叫工具,不過有一定的侷限性,畢竟是JAVA語言最開始時的設計,後來很多框架的原理都基於RMI,RMI的使用如下:
對外介面
服務實現
RMI客戶端
開源的優秀RPC框架
- 阿里巴巴 Dubbo:https://github.com/alibaba/dubbo
- 新浪微博 Motan:https://github.com/weibocom/motan
- gRPC:https://github.com/grpc/grpc
- rpcx :https://github.com/smallnest/rpcx
- Apache Thrift :https://thrift.apache.org/