根據網上搜索的一些資料摘抄匯總的,如果有誤,歡迎斧正。
早期單機時代,一台電腦上運行多個進程,大家各干各的,老死不相往來。假如A進程需要一個畫圖的功能,B進程也需要一個畫圖的功能,程序員就必須為兩個進程都寫一個畫圖的功能。這不是整人么?於是就出現了IPC(Inter-process communication,單機中運行的進程之間的相互通信)。OK,現在A既然有了畫圖的功能,B就調用A進程上的畫圖功能好了,程序員終於可以偷下懶了。
到了網絡時代,大家的電腦都連起來了。以前程序只能調用自己電腦上的進程,能不能調用其他機器上的進程呢?於是就程序員就把IPC擴展到網絡上,這就是RPC(遠程過程調用)了。現在不僅單機上的進程可以相互通信,多機器中的進程也可以相互通信了。
要知道實現RPC很麻煩呀,什么多線程、什么Socket、什么I/O,都是讓咱們普通程序員很頭疼的事情。於是就有牛人開發出RPC框架(比如,CORBA、RMI、Web Services、RESTful Web Services等等)。
OK,現在可以定義RPC框架的概念了。簡單點講,RPC框架就是可以讓程序員來調用遠程進程上的代碼一套工具。有了RPC框架,咱程序員就輕松很多了,終於可以逃離多線程、Socket、I/O的苦海了。
===================================================
到了網絡時代,大家的電腦都連起來了。以前程序只能調用自己電腦上的進程,能不能調用其他機器上的進程呢?於是就程序員就把IPC擴展到網絡上,這就是RPC(遠程過程調用)了。現在不僅單機上的進程可以相互通信,多機器中的進程也可以相互通信了。
要知道實現RPC很麻煩呀,什么多線程、什么Socket、什么I/O,都是讓咱們普通程序員很頭疼的事情。於是就有牛人開發出RPC框架(比如,CORBA、RMI、Web Services、RESTful Web Services等等)。
OK,現在可以定義RPC框架的概念了。簡單點講,RPC框架就是可以讓程序員來調用遠程進程上的代碼一套工具。有了RPC框架,咱程序員就輕松很多了,終於可以逃離多線程、Socket、I/O的苦海了。
===================================================
首先了解什么叫RPC,為什么要RPC,RPC是指遠程過程調用,也就是說兩台服務器A,B,一個應用部署在A服務器上,想要調用B服務器上應用提供的函數/方法,由於不在一個內存空間,不能直接調用,需要通過網絡來表達調用的語義和傳達調用的數據。
比如說,一個方法可能是這樣定義的:
Employee getEmployeeByName(String fullName)
比如說,一個方法可能是這樣定義的:
Employee getEmployeeByName(String fullName)
那么:
- 首先,要解決通訊的問題,主要是通過在客戶端和服務器之間建立TCP連接,遠程過程調用的所有交換的數據都在這個連接里傳輸。連接可以是按需連接,調用結束后就斷掉,也可以是長連接,多個遠程過程調用共享同一個連接。
- 第二,要解決尋址的問題,也就是說,A服務器上的應用怎么告訴底層的RPC框架,如何連接到B服務器(如主機或IP地址)以及特定的端口,方法的名稱名稱是什么,這樣才能完成調用。比如基於Web服務協議棧的RPC,就要提供一個endpoint URI,或者是從UDDI服務上查找。如果是RMI調用的話,還需要一個RMI Registry來注冊服務的地址。
- 第三,當A服務器上的應用發起遠程過程調用時,方法的參數需要通過底層的網絡協議如TCP傳遞到B服務器,由於網絡協議是基於二進制的,內存中的參數的值要序列化成二進制的形式,也就是序列化(Serialize)或編組(marshal),通過尋址和傳輸將序列化的二進制發送給B服務器。
- 第四,B服務器收到請求后,需要對參數進行反序列化(序列化的逆操作),恢復為內存中的表達方式,然后找到對應的方法(尋址的一部分)進行本地調用,然后得到返回值。
- 第五,返回值還要發送回服務器A上的應用,也要經過序列化的方式發送,服務器A接到后,再反序列化,恢復為內存中的表達方式,交給A服務器上的應用
為什么RPC呢?就是無法在一個進程內,甚至一個計算機內通過本地調用的方式完成的需求,比如比如不同的系統間的通訊,甚至不同的組織間的通訊。由於計算能力需要橫向擴展,需要在多台機器組成的集群上部署應用,
RPC的協議有很多,比如最早的CORBA,Java RMI,Web Service的RPC風格,Hessian,Thrift,甚至Rest API。
RPC(遠程過程調用)是什么
- 簡單的說,RPC就是從一台機器(客戶端)上通過參數傳遞的方式調用另一台機器(服務器)上的一個函數或方法(可以統稱為服務)並得到返回的結果。
- RPC 會隱藏底層的通訊細節(不需要直接處理Socket通訊或Http通訊)
- RPC 是一個請求響應模型。客戶端發起請求,服務器返回響應(類似於Http的工作方式)
- RPC 在使用形式上像調用本地函數(或方法)一樣去調用遠程的函數(或方法)。
遠程過程調用發展歷程
- ONC RPC (開放網絡計算的遠程過程調用),OSF RPC(開放軟件基金會的遠程過程調用)
- CORBA(Common Object Request Broker Architecture公共對象請求代理體系結構)
- DCOM(分布式組件對象模型),COM+
- Java RMI
- .NET Remoting
- XML-RPC,SOAP,Web Service
- PHPRPC,Hessian,JSON-RPC
- Microsoft WCF,WebAPI
- ZeroC Ice,Thrift,GRPC
- Hprose
早期的 RPC
- 第一代 RPC(ONC RPC,OSF RPC)不支持對象的傳遞。
- CORBA 太復雜,各種不同實現不兼容,一般程序員也玩不轉。
- DCOM,COM+ 逃不出 Windows 的手掌心。
- RMI 只能在 Java 里面玩。
- .NET Remoting 只能在 .NET 平台上玩。
XML-RPC,SOAP,WebService
- 冗余數據太多,處理速度太慢。
- RPC 風格的 Web Service 跨語言性不佳,而 Document 風格的 Web Service 又太過難用。
- Web Service 沒有解決用戶的真正問題,只是把一個問題變成了另一個問題。
- Web Service 的規范太過復雜,以至於在 .NET 和 Java 平台以外沒有真正好用的實現,甚至沒有可用的實現。
- 跨語言跨平台只是 Web Service 的一個口號,雖然很多人迷信這一點,但事實上它並沒有真正實現。
PHPRPC
- 基於 PHP 內置的序列化格式,在跨語言的類型映射上存在硬傷。
- 通訊上依賴於 HTTP 協議,沒有其它底層通訊方式的選擇。
- 內置的加密傳輸既是特點,也是缺點。
- 雖然比基於 XML 的 RPC 速度快,但還不是足夠快。
Hessian
- 二進制的數據格式完全不具有可讀性。
- 官方只提供了兩個半語言的實現(Java,ActionScript 和不怎么完美的 Python 實現),其它語言的第三方實現良莠不齊。
- 支持的語言不夠多,對 Web 前端的 JavaScript 完全無視。
- 雖然是動態 RPC,但動態性仍然欠佳。
- 雖然比基於 XML 的 RPC 速度快,但還不是足夠快。
JSON-RPC
- JSON 具有文本可讀性,且比 XML 更簡潔。
- JSON 受 JavaScript 語言子集的限制,可表示的數據類型不夠多。
- JSON 格式無法表示數據內的自引用,互引用和循環引用。
- 某些語言具有多種版本的實現,但在類型影射上沒有統一標准,存在兼容性問題。
- JSON-RPC 雖然有規范,但是卻沒有統一的實現。在不同語言中的各自實現存在兼容性問題,無法真正互通。
Microsoft WCF,WebAPI
- 它們是微軟對已有技術的一個 .NET 平台上的統一封裝,是對 .NET Remoting、WebService 和基於 JSON 、XML 等數據格式的 REST 風格的服務等技術的一個整合。
- 雖然號稱可以在 .NET 平台以外來調用它的這些服務,但實際上跟在 .NET 平台內調用完全是兩碼事。它沒有提供任何在其他平台的語言中可以使用的任何工具。
ZeroC Ice,Thrift,GRPC
- 初代 RPC 技術的跨語言面向對象的回歸。
- 仍然需要通過中間語言來編寫類型和接口定義。
- 仍然需要用代碼生成器來將中間語言編寫的類型和接口定義翻譯成你所使用的編程語言的客戶端和服務器端的占位程序(stub)。
- 你必須要基於生成的服務器代碼來單獨編寫服務,而不能將已有代碼直接作為服務發布。
- 你必須要用生成的客戶端代碼來調用服務,而沒有其它更靈活的方式。
- 如果你的中間代碼做了修改,以上所有步驟你都要至少重復一遍。
Hprose
- 無侵入式設計,不需要單獨定義類型,不需要單獨編寫服務,已有代碼可以直接發布為服務。
- 具有豐富的數據類型和完美的跨語言類型映射,支持自引用,互引用和循環引用數據。
- 支持眾多傳輸方式,如 HTTP、TCP、Websocket 等。
- 客戶端具有更靈活的調用方式,支持同步調用,異步調用,動態參數,可變參數,引用參數傳遞,多結果返回(Golang)等語言特征,Hprose 2.0 甚至支持推送。
- 具有良好的可擴展性,可以通過過濾器和中間件實現加密、壓縮、緩存、代理等各種功能性擴展。
- 兼容的無差別跨語言調用
- 支持更多的常用語言和平台
- 支持瀏覽器端的跨域調用
- 沒有中間語言,無需學習成本
- 性能卓越,使用簡單