RPC架構(gòu)
一、RPC概述
RPC(Remote Procedure Call)叫作遠(yuǎn)程過(guò)程調(diào)用,它是利用網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)上請(qǐng)求服務(wù),可以理解為把程序的一部分放在其他遠(yuǎn)程計(jì)算機(jī)上執(zhí)行。通過(guò)網(wǎng)絡(luò)通信將調(diào)用請(qǐng)求發(fā)送至遠(yuǎn)程計(jì)算機(jī)后,利用遠(yuǎn)程計(jì)算機(jī)的系統(tǒng)資源執(zhí)行這部分程序,最終返回遠(yuǎn)程計(jì)算機(jī)上的執(zhí)行結(jié)果。
RPC的五個(gè)主要部分
- user(服務(wù)調(diào)用方)
- user-stub(調(diào)用方的本地存根)
- RPCRuntime(RPC通信者)
- server-stub(服務(wù)端的本地存根)
- server(服務(wù)端)
服務(wù)調(diào)用方、調(diào)用方的本地存根及其一個(gè)RPC通信包的實(shí)例存在于調(diào)用者的機(jī)器上;而服務(wù)提供方、服務(wù)提供方的存根及另一個(gè)RPC通信包的實(shí)例存在于被調(diào)用的機(jī)器上。
服務(wù)方的代碼啟動(dòng)后要能夠接受調(diào)用方的網(wǎng)絡(luò)請(qǐng)求(如Netty、Tomcat)
從一個(gè)簡(jiǎn)單的案例分析
- Provider模塊為服務(wù)方,提供服務(wù)(接口)的實(shí)現(xiàn),接收調(diào)用方的調(diào)用(網(wǎng)絡(luò)請(qǐng)求),并返回執(zhí)行結(jié)果
- Consumer模塊為調(diào)用方,發(fā)送請(qǐng)求給服務(wù)方,并接受執(zhí)行結(jié)果
- Common模塊為公共模塊,提供服務(wù)(接口)的定義。供Provider和Consumer使用
- RPC模塊為RPC架構(gòu)的實(shí)現(xiàn)框架
- 提供網(wǎng)絡(luò)服務(wù)的啟動(dòng)(HttpServer)
- 提供網(wǎng)絡(luò)請(qǐng)求的處理(HttpServerHandler)
- 提供接口名和實(shí)現(xiàn)類(lèi)的映射,便于快速找到網(wǎng)絡(luò)請(qǐng)求調(diào)用方法對(duì)應(yīng)的實(shí)現(xiàn)類(lèi)(LocalRegister,這里使用本地注冊(cè))
- 提供網(wǎng)絡(luò)請(qǐng)求中接口名,方法名,參數(shù)類(lèi)型數(shù)組,參數(shù)數(shù)組的封裝(Invocation,需要實(shí)現(xiàn)序列化接口)
- 提供代理工廠類(lèi)用于Consumer創(chuàng)建代理對(duì)象,通過(guò)代理對(duì)象直接調(diào)用服務(wù)中的方法(ProxyFactory,通過(guò)JDK中的動(dòng)態(tài)代理類(lèi)Proxy實(shí)現(xiàn))
二、RPC框架的開(kāi)發(fā)要點(diǎn)
服務(wù)發(fā)現(xiàn)
從遠(yuǎn)程注冊(cè)中心(如Redis)獲取接口名對(duì)應(yīng)的ip地址和端口(URL列表)
List<URL> urlList = RemoteRegister.get(interfaceClass.getName(), "1.0");
負(fù)載均衡
負(fù)載均衡(LoadBalance)提供很多種策略,這里實(shí)現(xiàn)隨機(jī)策略
public class LoadBalance {
public static URL random(List<URL> urls){
Random random = new Random();
int randomIndex = random.nextInt(urls.size());
return urls.get(randomIndex);
}
}
服務(wù)容錯(cuò)
在可能會(huì)出現(xiàn)異常的位置進(jìn)行異常的友好處理,例如在網(wǎng)絡(luò)連接失敗時(shí)返回具體的信息
也可以在catch中調(diào)用自定義的實(shí)現(xiàn)類(lèi)HelloServiceErrorCallback調(diào)用具體的錯(cuò)誤回調(diào)方法
//服務(wù)調(diào)用:發(fā)送請(qǐng)求
String result = null;
try {
HttpClient client = new HttpClient();
result = client.send(url.getHostname(), url.getPort(), invocation);
}catch (Exception e){
return "服務(wù)調(diào)用失敗!";
}
服務(wù)重試
當(dāng)某個(gè)服務(wù)調(diào)用失敗后,可以嘗試調(diào)用集群中的其他服務(wù)
服務(wù)mock
若服務(wù)方的業(yè)務(wù)代碼沒(méi)有開(kāi)發(fā)完,調(diào)用方需要一個(gè)返回結(jié)果,就可以用mock實(shí)現(xiàn)。
在代理對(duì)象的調(diào)用邏輯中判斷是否有mock參數(shù)的信息,如果有直接返回mock中的信息文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-612222.html
String mock = System.getProperty("mock");
if( mock != null && mock.startsWith("return:")){
String result = mock.replace("return:", "");
return result;
}
三、案例代碼實(shí)現(xiàn)
獲取源碼可以去看我的Github文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-612222.html
RPC模塊中需要的依賴(lài)
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.43</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
到了這里,關(guān)于【Java框架】RPC遠(yuǎn)程調(diào)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!