由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

1、引言

經常有開發者在糾結怎麼開發IM集羣,雖然真正的使用人數,可能用個人電腦單機都能支撐。

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

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

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

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

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

  • 1)IM聊天消息首先會由用戶A發往IM實例1;
  • 2)IM實例1會將此條消息轉交給IM實例2;
  • 3)IM實例2會將此條消息最終投遞給連接在本實例上的用戶B。

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

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

此時,RPC技術出場了!

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

▲ 上圖是個典型的分佈式IM架構,注意中間的“RPC通信”字樣

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

2、正文概述

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

但是呢,爲了能夠更好的讓各位老鐵去學習相關的技術,我給大家一張技術路線圖,今天沒有講到的知識後面還會更新,等不及的朋友可以根據這張圖去查找相關的資料學習,也可以私信“資料”獲取

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

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

  • 1)什麼是RPC;
  • 2)爲什麼需要RPC;
  • 3)RPC的重要組件;
  • 4)常見RPC框架和各自特點。

3、什麼是RPC?

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

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

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

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

  • 1)爲啥要用別人家的東西——請求其他服務);
  • 2)我怎麼可以借到別人家的東西——其他服務調用;
  • 3)要是借用的話哪種形式更好——確定一個合適的調用方法);
  • 4)怎麼讓我用別人東西像自己的一樣——屏蔽底層細節透明通信)。

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

4、爲什麼需要RPC?

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

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

 

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

▲ 上圖中的分佈系統內部,就是用RPC實現的

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

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

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

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

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

 

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

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

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

 

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

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

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

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

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

 

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

▲ 典型的RPC調用過程

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

  • 1)客戶端(client)以本地調用方式調用服務;
  • 2)客戶端存根(client stub)接收到調用後,負責將方法、參數等組裝成能夠進行網絡傳輸的消息體(將消息體對象序列化爲二進制);
  • 3)客戶端通過 sockets 將消息發送到服務端;
  • 4)服務端存根(server stub)收到消息後進行解碼(將消息對象反序列化);
  • 5)服務端存根(server stub)根據解碼結果調用本地的服務;
  • 6)本地服務執行並將結果返回給服務端存根(server stub);
  • 7)服務端存根(server stub)將返回結果打包成消息(將結果消息對象序列化);
  • 8)服務端(server)通過 sockets 將消息發送到客戶端;
  • 9)客戶端存根(client stub)接收到結果消息,並進行解碼(將結果消息發序列化);
  • 10)客戶端(client)得到最終結果。

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

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

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

在知乎上看到了這個很有趣的問題

http好比普通話,rpc好比團伙內部黑化

講普通話,好處就是誰都聽得懂,誰都會講

講黑話,好處是可以更精簡,更加保密,更加可定製,壞處就是說黑話的哪一方(client端)也要懂,而且一旦大家都說一種黑話了,換黑話就困難了

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

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

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

8、典型的RPC框架

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

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

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

一個 RPC 最重要的功能模塊,就是上圖中的”RPC 協議”部分:

由IM集羣引發對於RPC的思考,學會了,面試官都不想問你RPC的問題

 

其中的序列化和反序列化的意思是:

  • 1)序列化:將數據結構或對象轉換成二進制串的過程;
  • 2)反序列化:將序列化中所生成的二進制串轉換成數據結構或者對象的過程。

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

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

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

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

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

常見 RPC 技術和框架有:

  • 1)應用級的服務框架:阿里的 Dubbo/Dubbox、Google gRPC、Spring Boot/Spring Cloud。
  • 2)遠程通信協議:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。
  • 3)通信框架:MINA 和 Netty。

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

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

  • 1)gRPC:是 Google 公佈的開源軟件,基於最新的 HTTP 2.0 協議,並支持常見的衆多編程語言。RPC 框架是基於 HTTP 協議實現的,底層使用到了 Netty 框架的支持;
  • 2)Thrift:是 Facebook 的開源 RPC 框架,主要是一個跨語言的服務開發框架。用戶只要在其之上進行二次開發就行,應用對於底層的 RPC 通訊等都是透明的。不過這個對於用戶來說需要學習特定領域語言這個特性,還是有一定成本的;
  • 3)Dubbo:是阿里集團開源的一個極爲出名的 RPC 框架,在很多互聯網公司和企業應用中廣泛使用。協議和序列化框架都可以插拔是極其鮮明的特色

好了,關於RPC的相應知識點到這裏就結束了,不知道這些知識點的整理大家覺得怎麼樣,覺得寫得不錯的,點個贊支持一下吧

關注公衆號:Java架構師聯盟,每日更新技術好文

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