1. 程式人生 > >RPC和WebService的區別

RPC和WebService的區別

最近分析的這個系統,邏輯架構中有一層是RPC interface。之前對RPC不熟悉,就上網搜尋了一下資料,在此總結一下:

RPC是Remote Procedure Calling,遠端過程呼叫的縮寫。並不是“遠端程序呼叫”——Remote Process Calling。RPC總的來說是一個Client/Server的結構,提供服務的一方稱為Server,消費服務的一方稱為Client。  下圖是本地過程呼叫,所有的過程都在本地伺服器上,依次呼叫即可。

下圖則是所謂的遠端過程呼叫,需要在Client和Server中互動。

因此,兩種呼叫方式,會產生什麼區別呢?  1、網路傳輸的開銷和程式設計的額外複雜性。 2、本地過程呼叫中,過程在同一塊實體記憶體中,因此就可以傳遞指標了。而遠端過程呼叫則不能,因為遠端過程與呼叫者執行在完全不同的地址空間中。  3、遠端過程不能共享呼叫者的環境,所以它就無法直接訪問呼叫者的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要素:  1、server必須釋出服務。  2、在client和server兩端都需要有模組來處理協議和連線。  3、server釋出的服務,需要將介面給到client。  當然,應用協議是什麼樣的,怎麼連線,服務介面怎麼給到client,是可以自行實現的,選擇餘地很大。但是RPC協議提供了一種標準的建議,如果沒有特別的理由,我認為沒有必要自行實現,但是清楚這個原理,總是好的。 最後回到我最近正在分析的系統上來說。本文一開始就提到,它的架構中有一個RPC Interface。  由於這不是一個開源系統,所以我並不清楚它的RPC Interface的實現,也就是說,我並不清楚它的應用協議和傳輸協議是什麼。姑且假設它是用的標準RPC協議的。  但是它將server服務釋出給client的方式,是向client提供了API,對JAVA平臺的程式設計師來說,就是一個xxx.jar。  這個jar包裡,有2部分內容:  1、client stub,包括介面和封裝過的資料結構。即ServerService,和XXXForm、XXXFilter等。那對於client程式設計師來說,就只需要呼叫ServerService.xxxx()的方法,並組裝XXXForm物件作為引數即可,類似 

Java程式碼  

  1. public interface ServerService{  
  2.     public XXXFilter giveMeTheFilter(XXXForm form);  
  3. }  

程式設計師只需要關心怎麼封裝合適的XXXForm,以及什麼時候呼叫giveMeTheFilter()方法即可,底層的協議,server端的實現,對client程式設計師來說都是透明的。  2、RPC Interface層的實現。這部分就做了協議解析、連線處理、異常處理等,但這部分類,是不對client程式設計師開放的。這種通過API(SDK),向client釋出服務的方式,我認為是有可取之處的。