想開發 IM 集羣?先搞懂什麼是 RPC!

1、引言

即時通訊網官方技術羣和社區裏,經常有開發者在糾結怎麼開發 IM 集羣,雖然真正的使用人數,可能用個人電腦單機都能支撐。

你會說,明明不需要用到 IM 集羣,幹嗎要自找麻煩?答曰:“老闆說這個得有!”、“萬一產品做成了,用戶量達到百萬、千萬級呢?”,各種回答,反此種種。總之,IM 集羣就是得整一個(先甭管用不用的上...)。

當然,玩笑歸玩笑,真正要做到可投入到生產級別的 IM 集羣系統,難度還是相當大的。必竟 IM 這種長連接應用相比傳統 Http 這種短連接應用太不標準。

我們以一個典型的 IM 聊天消息傳輸爲例:

假設存在兩個正在聊天的用戶(用戶 A 和用戶 B),當 A 連接的是 IM 集羣中的 IM 實例 1、B 連接的是 IM 集羣中的 IM 實例 2,此時當用戶 A 向用戶 B 發送一條聊天消息時,這條消息應該如何傳遞呢?

我們梳理一下上面這個例子的消息流轉過程:

如上述流程所示,這就是一個 IM 集羣系統中典型的聊天消息投遞過程。

那麼,這其中涉及到一個關鍵步驟:即第 2)步中如何實現 “IM 實例 1 會將此條消息轉交給 IM 實例 2”?

此時,RPC 技術出場了!

 ▲ 上圖是個典型的分佈式 IM 架構,注意中間的 “RPC 通信” 字樣(本圖引用自《基於 Go 的馬蜂窩旅遊網分佈式 IM 系統技術實踐》)

本文將以通俗易懂的白話形式,幫你快速理解 IM 集羣中的關鍵技術——RPC。

2、正文概述

限於篇幅原因,本文不會深入展開 RPC 的底層技術原理,會盡量用通俗白話的方式對概念性的東西進行講解。

通過本文你將主要了解到以下內容:

3、什麼是 RPC?

RPC 是 1984 年代由 Andrew D. Birrell & Bruce Jay Nelson 提出的(見二位大佬的論文《Implementing Remote Procedure Calls》),所以它並不是最近纔有的技術概念。

關於 RPC 的介紹,正經的資料上大概是這樣介紹的:

RPC(Remote Procedure Call)遠程過程調用,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。也就是說兩臺服務器 A,B,一個應用部署在 A 服務器上,想要調用 B 服務器上應用提供的方法,由於不在一個內存空間,不能直接調用,需要通過網絡來表達調用的語義和傳達調用的數據。

大白話理解 RPC 就是:RPC 讓你用別人家的東西就像自己家的一樣。

看得我似懂非懂,於是我不得不問幾個問題:

在解答這些問題之前,我們必須達到一個共識問題:RPC 只是一種通信模式,和 http 並不衝突對立,相反 http 可以作爲 RPC 傳輸數據的一種協議,把 RPC 當作一種模式和思想,我們才能更好地理解它。

更嚴謹的 RPC 基礎知識介紹,請閱讀:《即時通訊新手入門:快速理解 RPC 技術——基本概念、原理和用途》。

4、爲什麼需要 RPC?

以大家最熟悉的電商系統爲例,這樣規模的分佈式系統,需要拆分出用戶服務、商品服務、優惠券服務、支付服務、訂單服務、物流服務、售後服務等等。這些服務之間都相互調用,這時內部調用最好使用 RPC ,同時每個服務都可以獨立部署,獨立上線。 

也就說當我們的項目太大,需要解耦服務,擴展性強、部署靈活,這時就要用到 RPC ,這主要是解決了分佈式系統中,服務與服務之間的調用問題。

 ▲ 上圖中的分佈系統內部,就是用 RPC 實現的(本圖引用自《從新手到架構師,一篇就夠:從 100 到 1000 萬高併發的架構演進之路》)

對於 IM 集羣這樣的分佈式系統來說,不同 IM 實例間的用戶聊天消息,就是通過 RPC 進行流轉的。

5、爲什麼不直接使用 HTTP,而要搞 RPC?

在日常業務中我們可以把功能封裝成靜態庫、動態庫、sdk、獨立服務等,最常見也最方便的還是 HTTP 這種形式的調用。

HTTP 服務把需要提供的服務暴露成接口(也就是通常所說的 http rest 接口啦),使用方直接按約定的 HTTP 方法和 URI 進行數據交互。

我們都知道 HTTP 協議是應用層協議,是個非常標準的協議,在 HTTP 協議之下還有網絡層、傳輸層、數據鏈路層等,一個數據包 packet 除了淨荷 payload 之外還有很多 header,由於標準和通用性的設計目標也使得 HTTP 一次數據交互真正傳輸的 payload 只是其中一部分。

 

HTTP 是我們用的最多最熟悉的交互模式,在系統內部各個服務之間接口較少,交互不多的情況下工作得還不錯。

但如果在內部系統調用很複雜的前提下,HTTP 調用的效率和安全性就不那麼理想了。

 

以 IM 系統爲例,單個 IM 實例的吞吐效率至少可以達到幾萬甚至數十萬 QPS,使用 HTTP 這種短連接(調用時建立 socket 連接,完成後釋放連接)方式顯的相當低效(每次調用都要重新經歷 TCP 的 3 次握手、4 次揮手過程),在分佈式的情況下勢必拉低整個 IM 集羣的吞吐效率。而對於 RPC,這種 socket 長連接方式對於高性能場景來說,效果是顯而易見的。

更重要的是面對衆多的服務我們需要的不僅僅是一個通信方式,而是一個內部服務的管理系統,這也就是我們今天說的 RPC 框架。注意:RPC 是一種模式策略和框架,並不是單純的通信協議。

題外話:實際上,HTTP 在 RPC 系統中,並不是個你死我活的關係,必竟 HTTP 只是個通信協議,而 HTTP 有某些性能要求不敏感的場景來說,是完全可以作爲 RPC 的具體實現協議之一來使用的。

6、RPC 的調用過程是什麼樣的?

 
▲ 典型的 RPC 調用過程

如上圖所示,一個典型的 RPC 調用過程是這樣(過程序號對應上圖中的數字):

RPC 的作用,其實就是要把上述 2、3、4、7、8、9 這些步驟都封裝起來。是不是很神奇?

7、關於 HTTP 和 RPC 的一些爭議

HTTP 和 RPC 是兩個很容易混淆的概念,對於剛開始接觸 RPC 的人來說,通常都會困惑:有 HTTP 了爲什麼還要用 RPC?

在知乎上看到了這個很有趣的問題:《既然有 http 請求,爲什麼還要用 rpc?》

其中一個大佬的回答感覺很有意思:
 
換個角度來說:HTTP 與 RPC 的關係就好比普通話與方言的關係。要進行跨企業服務調用時,往往都是通過 HTTP API,也就是普通話,雖然效率不高,但是通用,沒有太多溝通的學習成本。但是在企業內部還是 RPC 更加高效,同一個企業公用一套方言進行高效率的交流,要比通用的 HTTP 協議來交流更加節省資源。整個中國有非常多的方言,正如有很多的企業內部服務各有自己的一套交互協議一樣。雖然國家一直在提倡使用普通話交流,但是這麼多年過去了,你回一趟家鄉探個親什麼的就會發現身邊的人還是流行說方言。

如果再深入一點說,普通話本質上也是一種方言,只不過它是官方的方言,使用最爲廣泛的方言,相比而言其它方言都是小語種,小語種之中也會有幾個使用比較廣泛比較特色的方言佔比也會比較大。這就好比開源 RPC 協議中 Protobuf 和 Thrift 一樣,它們兩應該是 RPC 協議中使用最爲廣泛的兩個。

總之:RPC 是一種編程模式和概念,並不是非常具體的一種技術,實際上和 HTTP 沒有明確的衝突,HTTP 可以作爲 RPC 傳輸協議,原因還是 RPCpid 際上是一種內部服務框架而不是一個具體的通信協議,它可以涉及服務註冊、服務治理、服務發現、熔斷機制、負載均衡等。

8、典型的 RPC 框架

一個典型 RPC 框架中,包含了服務發現、負載、容錯、網絡傳輸、序列化等組件,其中 “RPC 協議” 就指明瞭程序如何進行網絡傳輸和序列化。

 ▲ 一個典型的 RPC 架構原理圖(本圖引用自《即時通訊新手入門:快速理解 RPC 技術——基本概念、原理和用途》)

 ▲ 著名 RPC 框架 Dubbo 的架構圖(本圖引用自《即時通訊新手入門:快速理解 RPC 技術——基本概念、原理和用途》)

一個 RPC 最重要的功能模塊,就是上圖中的”RPC 協議” 部分:
 
其中的序列化和反序列化的意思是:

在網絡消息傳輸中可以基於 TCP、UDP、http 來實現,各自都有各自的特點。

基於 TCP 實現的 RPC 調用,能夠靈活對協議字段進行定製,減少網絡開銷提高性能,實現更大的吞吐量和併發數,但要關注底層細節,在進行數據解析時更加複雜一些(比如最受歡迎的 Protobuf 的使用)。

基於 HTTP 實現的 RPC 可以使用 JSON 和 XML 格式的請求或響應數據,解析工具很成熟,在其上進行二次開發會非常便捷和簡單。但是 HTTP 是上層協議,所佔用的字節數會比使用 TCP 協議傳輸所佔用的字節數更高。

對於其他部分,本文不再展開。

9、市面上常見的 RPC 框架及其特點

常見 RPC 技術和框架有:

目前流行的開源 RPC 框架還是比較多的,有阿里巴巴的 Dubbo、Facebook 的 Thrift、Google 的 gRPC、Twitter 的 Finagle 等。

下面重點介紹當前最流行的三種 RPC 框架主要特點:

10、本文小結

小結一下,簡單地理解 RPC 就是:

RPC 就是從一臺機器(客戶端)上通過參數傳遞的方式調用另一臺機器(服務器)上的一個函數或方法(可以統稱爲服務)並得到返回的結果。

RPC 會隱藏底層的通訊細節(不需要直接處理 Socket 通訊或 Http 通訊)。

RPC 是一個請求響應模型。客戶端發起請求,服務器返回響應(類似於 Http 的工作方式)。

RPC 在使用形式上像調用本地函數(或方法)一樣去調用遠程的函數(或方法)。

11、參考資料

[1] 什麼是 RPC 框架
[2] 誰能用通俗的語言解釋一下什麼是 RPC 框架?
[3] 淺談 RPC 那些事兒 [1]
[4] 即時通訊新手入門:快速理解 RPC 技術——基本概念、原理和用途
[5] 即時通訊新手入門:一文讀懂什麼是 Nginx?它能否實現 IM 的負載均衡?

附錄:文中引用的鏈接速查

1)《基於 Go 的馬蜂窩旅遊網分佈式 IM 系統技術實踐》

http://www.52im.net/thread-2909-1-1.html

2)《快速理解 RPC 技術——基本概念、原理和用途》

http://www.52im.net/thread-2620-1-1.html

3)《一文讀懂什麼是 Nginx?它能否實現 IM 的負載均衡?》

http://www.52im.net/thread-2600-1-1.html

4)《從新手到架構師,一篇就夠:從 100 到 1000 萬高併發的架構演進之路》

http://www.52im.net/thread-2665-1-1.html

5)《Protobuf 通信協議詳解:代碼演示、詳細原理介紹等》

http://www.52im.net/thread-323-1-1.html

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/mAzaR6B1YY1oCDEGDsEGZA