RPC深入淺出--淺出篇

本文來自本人獨立博客,爲獲得更佳閱讀體驗,請點擊 這裏

----------------------------------------------------------------------------------------------------


近幾年的項目中,服務化和微服務化漸漸成爲中大型分佈式系統架構的主流方式,而 RPC 在其中扮演着關鍵的作用。在平時的日常開發中我們都在隱式或顯式的使用 RPC,一些剛入行的程序員會感覺 RPC 比較神祕,而一些有多年使用 RPC 經驗的程序員雖然使用經驗豐富,但有些對其原理也不甚了了。缺乏對原理層面的理解,往往也會造成開發中的一些誤用。

本文分上下兩篇《淺出篇》和《深入篇》,其目標就是想嘗試深入淺出的分析下 RPC 本質,我總是這麼認爲理解了本質才能更好的應用。

RPC 是什麼?

RPC 的全稱是 Remote Procedure Call 是一種進程間通信方式。它允許程序調用另一個地址空間(通常是共享網絡的另一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。即程序員無論是調用本地的還是遠程的,本質上編寫的調用代碼基本相同。

RPC 起源

RPC 這個概念術語在上世紀 80 年代由 Bruce Jay Nelson 提出。這裏我們追溯下當初開發 RPC 的原動機是什麼?在 Nelson 的論文 "Implementing Remote Procedure Calls" 中他提到了幾點:

1. 簡單:RPC 概念的語義十分清晰和簡單,這樣建立分佈式計算就更容易。
2. 高效:過程調用看起來十分簡單而且高效。
3. 通用:在單機計算中過程往往是不同算法部分間最重要的通信機制。 

通俗一點說,就是一般程序員對於本地的過程調用很熟悉,那麼我們把 RPC 作成和本地調用完全類似,那麼就更容易被接受,使用起來毫無障礙。Nelson 的論文發表於 30 年前,其觀點今天看來確實高瞻遠矚,今天我們使用的 RPC 框架基本就是按這個目標來實現的。

RPC 結構

Nelson 的論文中指出實現 RPC 的程序包括 5 個部分:

1. User
2. User-stub
3. RPCRuntime
4. Server-stub
5. Server

這 5 個部分的關係如下圖所示

這裏 user 就是 client 端,當 user 想發起一個遠程調用時,它實際是通過本地調用 user-stub。user-stub 負責將調用的接口、方法和參數通過約定的協議規範進行編碼並通過本地的 RPCRuntime 實例傳輸到遠端的實例。遠端 RPCRuntime 實例收到請求後交給 server-stub 進行解碼後發起本地端調用,調用結果再返回給 user 端。

RPC 實現

Nelson 論文中給出的這個實現結構也成爲後來大家參考的標準範本。大約 10 年前,我最早接觸分佈式計算時使用的 CORBAR 實現結構基本與此類似。CORBAR 爲了解決異構平臺的 RPC,使用了 IDL(Interface Definition Language)來定義遠程接口,並將其映射到特定的平臺語言中。後來大部分的跨語言平臺 RPC 基本都採用了此類方式,比如我們熟悉的 Web Service(SOAP),近年開源的 Thrift 等。他們大部分都通過 IDL 定義,並提供工具來映射生成不同語言平臺的 user-stub 和 server-stub,並通過框架庫來提供 RPCRuntime 的支持。不過貌似每個不同的 RPC 框架都定義了各自不同的 IDL 格式,導致程序員的學習成本進一步上升(苦逼啊),Web Service 嘗試建立業界標準,無賴標準規範複雜而效率偏低,否則 Thrift 等更高效的 RPC 框架就沒必要出現了。

IDL 是爲了跨平臺語言實現 RPC 不得已的選擇,要解決更廣泛的問題自然導致了更復雜的方案。而對於同一平臺內的 RPC 而言顯然沒必要搞箇中間語言出來,例如 Java 原生的 RMI,這樣對於 java 程序員而言顯得更直接簡單,降低使用的學習成本。目前市面上提供的 RPC 框架已經可算是五花八門,百家爭鳴了。需要根據實際使用場景謹慎選型,需要考慮的選型因素我覺得至少包括下面幾點:

1. 性能指標
2. 是否需要跨語言平臺
3. 內網開放還是公網開放
4. 開源 RPC 框架本身的質量、社區活躍度

總結

《淺出篇》大概就到這裏結束了,《深入篇》會具體深入講解一個 RPC 框架需要實現哪裏基本功能,達到什麼目標,並以在 java 平臺上去具體實現一個 RPC 框架爲例,分析其需要考慮的實現因素。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章