RPC概述
RPC(Remote Procedure Call)即遠(yuǎn)程過程調(diào)用瓦哎,允許一臺(tái)計(jì)算機(jī)調(diào)用另一臺(tái)計(jì)算機(jī)上的程序得到結(jié)果漓藕,而代碼中不需要做額外的編程陶珠,就像在本地調(diào)用一樣。
現(xiàn)在互聯(lián)網(wǎng)應(yīng)用的量級(jí)越來越大享钞,單臺(tái)計(jì)算機(jī)的能力有限揍诽,需要借助可擴(kuò)展的計(jì)算機(jī)集群來完成,分布式的應(yīng)用可以借助RPC來完成機(jī)器之間的調(diào)用栗竖。
RPC框架原理
在RPC框架中主要有三個(gè)角色:Provider暑脆、Consumer和Registry。如下圖所示:
節(jié)點(diǎn)角色說明:
- Server: 暴露服務(wù)的服務(wù)提供方狐肢。
- Client: 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方添吗。
- Registry: 服務(wù)注冊與發(fā)現(xiàn)的注冊中心。
RPC調(diào)用流程
RPC基本流程圖:
一次完整的RPC調(diào)用流程(同步調(diào)用份名,異步另說)如下:
1)服務(wù)消費(fèi)方(client)調(diào)用以本地調(diào)用方式調(diào)用服務(wù)碟联;
2)client stub接收到調(diào)用后負(fù)責(zé)將方法、參數(shù)等組裝成能夠進(jìn)行網(wǎng)絡(luò)傳輸?shù)南Ⅲw同窘;
3)client stub找到服務(wù)地址玄帕,并將消息發(fā)送到服務(wù)端;
4)server stub收到消息后進(jìn)行解碼想邦;
5)server stub根據(jù)解碼結(jié)果調(diào)用本地的服務(wù)裤纹;
6)本地服務(wù)執(zhí)行并將結(jié)果返回給server stub;
7)server stub將返回結(jié)果打包成消息并發(fā)送至消費(fèi)方丧没;
8)client stub接收到消息鹰椒,并進(jìn)行解碼;
9)服務(wù)消費(fèi)方得到最終結(jié)果呕童。
RPC框架的目標(biāo)就是要2~8這些步驟都封裝起來漆际,讓用戶對(duì)這些細(xì)節(jié)透明。
服務(wù)注冊&發(fā)現(xiàn)
服務(wù)提供者啟動(dòng)后主動(dòng)向注冊中心注冊機(jī)器ip夺饲、port以及提供的服務(wù)列表奸汇;
服務(wù)消費(fèi)者啟動(dòng)時(shí)向注冊中心獲取服務(wù)提供方地址列表施符,可實(shí)現(xiàn)軟負(fù)載均衡和Failover;
使用到的技術(shù)
1擂找、動(dòng)態(tài)代理
生成 client stub和server stub需要用到 **Java 動(dòng)態(tài)代理技術(shù) **戳吝,我們可以使用JDK原生的動(dòng)態(tài)代理機(jī)制,可以使用一些開源字節(jié)碼工具框架 如:CgLib贯涎、Javassist等听哭。
2、序列化
為了能在網(wǎng)絡(luò)上傳輸和接收 Java對(duì)象塘雳,我們需要對(duì)它進(jìn)行 序列化和反序列化操作陆盘。
- 序列化:將Java對(duì)象轉(zhuǎn)換成byte[]的過程,也就是編碼的過程败明;
- 反序列化:將byte[]轉(zhuǎn)換成Java對(duì)象的過程隘马;
可以使用Java原生的序列化機(jī)制,但是效率非常低肩刃,推薦使用一些開源的祟霍、成熟的序列化技術(shù)杏头,例如:protobuf盈包、Thrift、hessian醇王、Kryo呢燥、Msgpack
關(guān)于序列化工具性能比較可以參考:jvm-serializers
3、NIO
當(dāng)前很多RPC框架都直接基于netty這一IO通信框架寓娩,比如阿里巴巴的HSF叛氨、dubbo,Hadoop Avro棘伴,推薦使用Netty 作為底層通信框架寞埠。
4、服務(wù)注冊中心
可選技術(shù):
- Redis
- Zookeeper
- Consul
- Etcd