RPC是Remote Procedure Calling,遠程過程調用的縮寫。並非「遠程進程調用」——Remote Process Calling。RPC總的來講是一個Client/Server的結構,提供服務的一方稱爲Server,消費服務的一方稱爲Client。
下圖是本地過程調用,全部的過程都在本地服務器上,依次調用便可。
下圖則是所謂的遠程過程調用,須要在Client和Server中交互。
所以,兩種調用方式,會產生什麼區別呢?
一、網絡傳輸的開銷和編程的額外複雜性。
二、本地過程調用中,過程在同一塊物理內存中,所以就能夠傳遞指針了。而遠程過程調用則不能,由於遠程過程與調用者運行在徹底不一樣的地址空間中。
三、遠程過程不能共享調用者的環境,因此它就沒法直接訪問調用者的I/O和操做系統API。
簡單來講,就是遠程過程調用會比本地過程調用複雜。除了性能的額外開銷以外,編程也複雜得多。
至少能夠想到,交互雙方須要可以封裝數據結構,理解協議,處理鏈接等等,確實是很麻煩的。可能一個很簡單的調用,卻須要作不少的編程工做。因此,爲了簡化RPC調用的編程,就提出了一個RPC的標準模型。
下面是RPC的原理草圖。
能夠看到,該模型中多了一個stub的組件,這個是約定的接口,也就是server提供的服務。注意這裏的「接口」,不是指JAVA中的interface,由於RPC是跨平臺跨語言的,用JAVA寫的客戶端,應該可以調用用C語言提供的過程。
對客戶端來講,有了這個stub,RPC調用過程對client code來講就變成透明的了,客戶端代碼不須要關心溝通的協議是什麼,網絡鏈接是怎麼創建的。對客戶端來講,它甚至不知道本身調用的是一個遠程過程,仍是一個本地過程。
而後,前面說的理解協議,處理鏈接的工做,老是要有人作的,這個工做就是在下面的RPC Interface裏完成的。
最近幾年,遇到這種場景(須要調用遠程機器上的服務),每每會考慮用web service來完成,其實我認爲web service和RPC是很是相像的,下面是web service的原理草圖
對比一下RPC草圖,就會發現很是的接近。在組件層次,和交互時序上徹底沒有差異,只是方框內的字不同,可是實際上承擔的職責倒是徹底對應的。
web service接口就是RPC中的stub組件,規定了server可以提供的服務(web service),這在server和client上是一致的,可是也是跨語言跨平臺的。同時,因爲web service規範中的WSDL文件的存在,如今各平臺的web service框架,均可以基於WSDL文件,自動生成web service接口。
下面的web service框架,根據所選的平臺有所不一樣,好比在JAVA平臺中,如今最流行的是apache的cxf框架。它作的事情也和RPC Interface是同樣的,負責解析協議(SOAP協議),負責處理鏈接(創建HTTP鏈接)。
所以,我認爲RPC和web service很是得接近,只是RPC的傳輸層協議,以及應用層協議,能夠自行實現,因此選擇的餘地更大一點。可能會在性能和傳輸效率上,有更大的優點(不必定) 。
和web service有不少成熟框架可供選擇同樣,RPC也有不少現成的框架可供選擇,好比在JAVA平臺上有nfs-rpc等。
總結來講,要實現遠程過程調用,須要有3要素:
一、server必須發佈服務。
二、在client和server兩端都須要有模塊來處理協議和鏈接。
三、server發佈的服務,須要將接口給到client。
固然,應用協議是什麼樣的,怎麼鏈接,服務接口怎麼給到client,是能夠自行實現的,選擇餘地很大。可是RPC協議提供了一種標準的建議,若是沒有特別的理由,我認爲沒有必要自行實現,可是清楚這個原理,老是好的。
最後回到我最近正在分析的系統上來講。本文一開始就提到,它的架構中有一個RPC Interface。
因爲這不是一個開源系統,因此我並不清楚它的RPC Interface的實現,也就是說,我並不清楚它的應用協議和傳輸協議是什麼。姑且假設它是用的標準RPC協議的。
可是它將server服務發佈給client的方式,是向client提供了API,對JAVA平臺的程序員來講,就是一個xxx.jar。
這個jar包裏,有2部份內容:
一、client stub,包括接口和封裝過的數據結構。即ServerService,和XXXForm、XXXFilter等。那對於client程序員來講,就只須要調用ServerService.xxxx()的方法,並組裝XXXForm對象做爲參數便可,相似
public interface ServerService{
public XXXFilter giveMeTheFilter(XXXForm form);
}
程序員只須要關心怎麼封裝合適的XXXForm,以及何時調用giveMeTheFilter()方法便可,底層的協議,server端的實現,對client程序員來講都是透明的。
二、RPC Interface層的實現。這部分就作了協議解析、鏈接處理、異常處理等,但這部分類,是不對client程序員開放的。這種經過API(SDK),向client發佈服務的方式,我認爲是有可取之處的。