RPC是什么
RPC(Remote Procedure Call Protocol)——遠程過程調(diào)用協(xié)議,它是一種通過網(wǎng)絡(luò)從遠程計算機程序上請求服務(wù)听系,而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。
RPC采用客戶機/服務(wù)器模式芝此。請求程序就是一個客戶機,而服務(wù)提供程序就是一個服務(wù)器。首先癌蓖,客戶機調(diào)用進程發(fā)送一個有進程參數(shù)的調(diào)用信息到服務(wù)進程,然后等待應(yīng)答信息婚肆。在服務(wù)器端租副,進程保持睡眠狀態(tài)直到調(diào)用信息到達為止。當(dāng)一個調(diào)用信息到達较性,服務(wù)器獲得進程參數(shù)用僧,計算結(jié)果,發(fā)送答復(fù)信息赞咙,然后等待下一個調(diào)用信息责循,最后,客戶端調(diào)用進程接收答復(fù)信息攀操,獲得進程結(jié)果院仿,然后調(diào)用執(zhí)行繼續(xù)進行。
以上是百度百科對RPC的解釋速和。
一個通俗的描述是:客戶端在不知道調(diào)用細(xì)節(jié)的情況下歹垫,調(diào)用存在于遠程計算機上的某個對象,就像調(diào)用本地應(yīng)用程序中的對象一樣颠放。
RPC產(chǎn)生的背景
早期單機時代排惨,一臺電腦上運行多個進程,大家各干各的碰凶,老死不相往來暮芭。假如A進程需要一個畫圖的功能,B進程也需要一個畫圖的功能欲低,程序員就必須為兩個進程都寫一個畫圖的功能辕宏。這不是整人么?于是就出現(xiàn)了IPC(Inter-process communication伸头,單機中運行的進程之間的相互通信)匾效。OK,現(xiàn)在A既然有了畫圖的功能恤磷,B就調(diào)用A進程上的畫圖功能好了面哼。
到了網(wǎng)絡(luò)時代,大家的電腦都連起來了扫步。以前程序只能調(diào)用自己電腦上的進程魔策,能不能調(diào)用其他機器上的進程呢?于是就程序員就把IPC擴展到網(wǎng)絡(luò)上河胎,這就有了RPC闯袒。
這個時候畫圖功能就可以作為一個獨立的服務(wù)提供給客戶機使用。
RPC框架特性
RPC是協(xié)議
既然是協(xié)議就只是一套規(guī)范,那么就需要有人遵循這套規(guī)范來進行實現(xiàn)政敢。目前典型的RPC實現(xiàn)包括:Dubbo其徙、Thrift、GRPC喷户、Hetty等唾那。
網(wǎng)絡(luò)協(xié)議和網(wǎng)絡(luò)IO透明
既然RPC的客戶端認(rèn)為自己是在調(diào)用本地對象。那么傳輸層使用的是TCP/UDP還是HTTP協(xié)議褪尝,者是一些其他的網(wǎng)絡(luò)協(xié)議它就不需要關(guān)心了闹获。既然網(wǎng)絡(luò)協(xié)議對其透明,那么調(diào)用過程中河哑,使用的是哪一種網(wǎng)絡(luò)IO模型調(diào)用者也不需要關(guān)心避诽。
信息格式對其透明
在本地應(yīng)用程序中,對象調(diào)用需要傳遞一些參數(shù)璃谨,會返回一個調(diào)用結(jié)果沙庐。對象內(nèi)部是如何使用這些參數(shù),并計算出處理結(jié)果的佳吞,調(diào)用方是不需要關(guān)心的轨功。那么對于RPC來說,這些參數(shù)會以某種信息格式傳遞給網(wǎng)絡(luò)上的另外一臺計算機容达,這個信息格式是怎樣構(gòu)成的古涧,調(diào)用方是不需要關(guān)心的。
有跨語言能力
調(diào)用方實際上也不清楚遠程服務(wù)器的應(yīng)用程序是使用什么語言運行的花盐。那么對于調(diào)用方來說羡滑,無論服務(wù)器方使用的是什么語言,本次調(diào)用都應(yīng)該成功算芯,并且返回值也應(yīng)該按照調(diào)用方程序語言所能理解的形式進行描述柒昏。
RPC框架的工作原理
1.調(diào)用客戶端句柄;執(zhí)行傳送參數(shù)
2.調(diào)用本地系統(tǒng)內(nèi)核發(fā)送網(wǎng)絡(luò)消息
3.消息傳送到遠程主機
4.服務(wù)器句柄得到消息并取得參數(shù)
5.執(zhí)行遠程過程
6.執(zhí)行的過程將結(jié)果返回服務(wù)器句柄
7.服務(wù)器句柄返回結(jié)果熙揍,調(diào)用遠程系統(tǒng)內(nèi)核
8.消息傳回本地主機
9.客戶句柄由內(nèi)核接收消息
10.客戶接收句柄返回的數(shù)據(jù)
自己實現(xiàn)RPC框架要做的工作
代碼實現(xiàn)要做的工作
1职祷、設(shè)計對外的接口
publicinterfaceIServiceextendsRemote?{
publicString?queryName(String?no)throwsRemoteException;
}
2、服務(wù)端的服務(wù)實現(xiàn)
publicclassServiceImplextendsUnicastRemoteObjectimplementsIService?{
privatestaticfinallongserialVersionUID?=?682805210518738166L;
protectedServiceImpl()throwsRemoteException?{
super();
}
@Override
publicString?queryName(String?no)throwsRemoteException?{
//方法的具體實現(xiàn)
return?String.valueOf(System.currentTimeMillis());
}
}
3届囚、RMI服務(wù)端實現(xiàn)
publicclassServer?{
publicstaticvoidmain(String[]?args)?{
Registry?registry?=null;
try{
//創(chuàng)建一個服務(wù)注冊管理器
registry?=?LocateRegistry.createRegistry(8088);
}catch(RemoteException?e)?{
}
try{
//創(chuàng)建一個服務(wù)
ServiceImpl?server?=newServiceImpl();
//將服務(wù)綁定命名
registry.rebind("vince",?server);
}catch(RemoteException?e)?{
}
}
}
4有梆、客戶端實現(xiàn)
publicclassClient?{
publicstaticvoidmain(String[]?args)?{
Registry?registry?=null;
try?{
//獲取服務(wù)注冊管理器
registry?=?LocateRegistry.getRegistry("127.0.0.1",8088);
}catch(RemoteException?e)?{
}
try?{
//根據(jù)命名獲取服務(wù)
IService?server?=?(IService)?registry.lookup("vince");
//調(diào)用遠程方法,獲取結(jié)果意系。
String?result?=?server.queryName("ha?ha?ha?ha");
}catch(Exception?e){
}
}
}
本文原創(chuàng)首發(fā)于Cobub官網(wǎng)博客泥耀,作者:許督洲
如有轉(zhuǎn)載請注明作者和出處!
推薦一款開源私有化部署的移動應(yīng)用數(shù)據(jù)統(tǒng)計分析系統(tǒng)Cobub Razor
項目地址:https://github.com/cobub/razor
官網(wǎng):www.cobub.com
開源社區(qū)技術(shù)交流QQ群:194022996