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

本文引用了後端技術指南針公衆號「淺談RPC那些事兒1」和即時通信網的「即時通信新手入門:快速理解RPC技術——基本概念、原理和用途」兩篇文章的部份內容。html

一、引言

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

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

固然,玩笑歸玩笑,真正要作到可投入到生產級別的IM集羣系統,難度仍是至關大的。必竟IM這種長鏈接應用相比傳統Http這種短鏈接應用太不標準。後端

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

假設存在兩個正在聊天的用戶(用戶A和用戶B),當A鏈接的是IM集羣中的IM實例一、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通訊」字樣本圖引用自《基於Go的馬蜂窩旅遊網分佈式IM系統技術實踐

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

本文已同步發佈於「即時通信技術圈」公衆號。

二、正文概述

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

經過本文你將主要了解到如下內容:

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

三、什麼是RPC?

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

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

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

大白話理解RPC就是:RPC讓你用別人家的東西就像本身家的同樣。

看得我似懂非懂,因而我不得不問幾個問題:

  • 1)爲啥要用別人家的東西——請求其餘服務);
  • 2)我怎麼能夠借到別人家的東西——其餘服務調用;
  • 3)要是借用的話哪一種形式更好——肯定一個合適的調用方法);
  • 4)怎麼讓我用別人東西像本身的同樣——屏蔽底層細節透明通訊)。

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

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

四、爲何須要RPC?

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

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

 

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

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

五、爲何不直接使用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的具體實現協議之一來使用的。

六、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的做用,其實就是要把上述二、三、四、七、八、9 這些步驟都封裝起來。是否是很神奇?

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

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

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

其中一個大佬的回答感受頗有意思: 

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

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

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

八、典型的RPC框架

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

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

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

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

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

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

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

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

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

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

九、市面上常見的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 框架,在不少互聯網公司和企業應用中普遍使用。協議和序列化框架均可以插拔是極其鮮明的特點。(本文同步發佈於:http://www.52im.net/thread-2996-1-1.html
相關文章
相關標籤/搜索