【修真院java小課堂】什麼是RMI,什麼是RPC,兩者之間的區別是什麼?
大家好,我是IT修真院北京分院第34期的學員嶽曉鵬,一枚正直純潔善良的java程式設計師,今天給大家分享一下,修真院官網java任務八,深度思考中的知識點——什麼是RMI,什麼是RPC,兩者之間的區別是什麼?
(1)背景介紹:
RMI
Java遠端方法呼叫,即Java RMI(Java Remote Method Invocation)是Java程式語言裡, 一種用於實現遠端過程呼叫的應用程式程式設計介面。它使客戶機上執行的程式可以呼叫遠端伺服器上的物件。 遠端方法呼叫特性使Java程式設計人員能夠在網路環境中分佈操作。RMI全部的宗旨就是儘可能簡化遠端介面物件的使用。 Java RMI極大地依賴於介面。在需要建立一個遠端物件的時候,程式設計師通過傳遞一個介面來隱藏底層的實現細節。 客戶端得到的遠端物件控制代碼正好與本地的根程式碼連線,由後者負責透過網路通訊。 這樣一來,程式設計師只需關心如何通過自己的介面控制代碼傳送訊息。
RPC
RPC 的全稱是 Remote Procedure Call 是一種程序間通訊方式。 它允許程式呼叫另一個地址空間(通常是共享網路的另一臺機器上)的過程或函式,而不用程式設計師顯式編碼這個遠端呼叫的細節。 即程式設計師無論是呼叫本地的還是遠端的,本質上編寫的呼叫程式碼基本相同。
(2)知識剖析:
RPC 與其它遠端呼叫方式比較
RPC 與 HTTP、RMI、Web Service 都能完成遠端呼叫,但是實現方式和側重點各有不同。
HTTP
HTTP(HyperText Transfer Protocol)是應用層通訊協議,使用標準語義訪問指定資源(圖片、介面等), 網路中的中轉伺服器能識別協議內容。HTTP 協議是一種資源訪問協議,通過 HTTP 協議可以完成遠端請求並返回請求結果。 HTTP 的優點是簡單、易用、可理解性強且語言無關 ,在遠端服務呼叫中包括微博有著廣泛應用。HTTP 的缺點是協議頭較重, 一般請求到具體伺服器的鏈路較長,可能會有 DNS 解析、Nginx 代理等。 RPC 是一種協議規範,可以把 HTTP 看作是一種 RPC 的實現,也可以把 HTTP 作為 RPC 的傳輸協議來應用。 RPC 服務的自動化程度比較高,能夠實現強大的服務治理功能,和語言結合更友好,效能也十分優秀。與 HTTP 相比, RPC 的缺點就是相對複雜,學習成本稍高。
RMI
RMI(Remote Method Invocation)是指 Java 語言中的遠端方法呼叫,RMI 中的每個方法都具有方法簽名, RMI 客戶端和伺服器端通過方法簽名進行遠端方法呼叫。RMI 只能在 Java 語言中使用, 可以把 RMI 看作面向物件的 Java RPC 。
Web Service
Web Service 是一種基於 Web 進行服務釋出、查詢、呼叫的架構方式,重點在於服務的管理與使用。Web Service 一般通過 WSDL 描述服務,使用 SOAP(簡單物件訪問協議)通過 HTTP 呼叫服務。 RPC 是一種遠端訪問協議,而 Web Service 是一種體系結構,Web Service 也可以通過 RPC 來進行服務呼叫,因此 Web Service 更適合同一個 RPC 框架進行比較。當 RPC 框架提供了服務的發現與管理,並使用 HTTP 作為傳輸協議時,其實就是 Web Service。 相對 Web Service,RPC 框架可以對服務進行更細粒度的治理,包括流量控制、SLA 管理等,在微服務化、分散式計算方面有更大的優勢。
RPC與RMI的區別
(1)RPC 跨語言,而 RMI只支援Java。
(2)RMI 呼叫遠端物件方法,允許方法返回 Java 物件以及基本資料型別,而RPC 不支援物件的概念, 傳送到 RPC 服務的訊息由外部資料表示 (External Data Representation, XDR) 語言表示, 這種語言抽象了位元組序類和資料型別結構之間的差異。只有由 XDR 定義的資料型別才能被傳遞, 可以說 RMI 是面向物件方式的 Java RPC 。
(3)在方法呼叫上,RMI中,遠端介面使每個遠端方法都具有方法簽名。如果一個方法在伺服器上執行,但是沒有相匹配的簽名被新增到這個遠端介面上,那麼這個新方法就不能被RMI客戶方所呼叫。
在RPC中,當一個請求到達RPC伺服器時,這個請求就包含了一個引數集和一個文字值,通常形成“classname.methodname”的形式。這就向RPC伺服器表明,被請求的方法在為 “classname”的類中,名叫“methodname”。然後RPC伺服器就去搜索與之相匹配的類和方法,並把它作為那種方法引數型別的輸入。這裡的引數型別是與RPC請求中的型別是匹配的。一旦匹配成功,這個方法就被呼叫了,其結果被編碼後返回客戶方。
RMI遠端呼叫步驟:
1,客戶呼叫客戶端輔助物件stub上的方法
2,客戶端輔助物件stub打包呼叫資訊(變數,方法名),通過網路傳送給服務端輔助物件skeleton
3,服務端輔助物件skeleton將客戶端輔助物件傳送來的資訊解包,找出真正被呼叫的方法以及該方法所在物件
4,呼叫真正服務物件上的真正方法,並將結果返回給服務端輔助物件skeleton
5,服務端輔助物件將結果打包,傳送給客戶端輔助物件stub
6,客戶端輔助物件將返回值解包,返回給呼叫者
7,客戶獲得返回值
(3)常見問題:
RMI進行遠端通訊的資料的傳遞
(4)解決方案:
在Java程式中引用型別的引數傳遞是按引用傳遞的,對於在同一個虛擬機器中的傳遞時是沒有問題的,因為的引數的引用對應的是同一個記憶體空間。但是對於分散式系統中,由於物件不再存在於同一個記憶體空間,虛擬機器A的物件引用對於虛擬機器B沒有任何意義 需要將物件序列化為流的形式,通過實現java.io.Serializable介面來完成。
(5)編碼實戰:
簡單的進行一個RMI的簡單呼叫
(6)拓展思考:
(7)參考文獻:
(8)更多討論:
Q1:什麼是uuid?遠端傳輸的時候需要uuid嗎? A1:UUID含義是通用唯一識別碼 (Universally Unique Identifier),是讓分散式系統中的所有元素,都能有唯一的辨識資訊,而不需要透過中央控制端來做辨識資訊的指定。如此一來,每個人都可以建立不與其它人衝突的 UUID。其實遠端傳輸序列化的時候,使用java自帶的雜湊計算和檢點指定一個uid就可以了,並不是一定需要uuid,用這個還是有點繁瑣。 Q2:怎麼保證遠端通訊的接受方可以正確的反序列化? A2:java中序列化的時候,是根據類的所有內容來計算出一個雜湊雜湊值,通過這個雜湊值來判斷是不是同一個類,計算的內容包括類全限定名稱,方法,屬性;只要是這個幾個內容一樣,並且雙方都用的同一種序列化方式來進行序列化和反序列化就可以正確的進行傳輸。 Q3:遠端通訊跟最近很火的微服務是不是一回事? A3:遠端通訊的技術很早就有,微服務的火爆是在遠端通訊基礎上構建的一個服務框架。學習微服務必須得熟悉遠端通訊的內容。
(9)鳴謝:
感謝白笑然、袁磊師兄,此教程是在他們之前技術分享的基礎上完善而成。
(10)結束語:
今天的分享就到這裡啦,歡迎大家點贊、轉發、留言、拍磚~