如何從0到1設計一個類Dubbo的RPC框架

mikechen的網際網路架構發表於2022-02-17

如何從0到1設計一個類Dubbo的RPC框架-mikechen的網際網路架構

之前分享了如何從0到1設計一個MQ訊息佇列,今天談談“如何從0到1設計一個Dubbo的RPC框架”,重點考驗:

  •  你對RPC框架的底層原理掌握程度。
  •  以及考驗你的整體RPC框架系統設計能力。

RPC和RPC框架

1.RPC(Remote Procedure Call)

即遠端過程呼叫, 主要解決遠端通訊間的問題,不需要了解底層網路的通訊機制。

2.RPC框架

RPC框架負責遮蔽底層的傳輸方式(TCP或者UDP)、序列化方式、以及通訊細節。

實際使用中,並不需要關心底層通訊細節和呼叫過程,讓業務端專注於業務程式碼的實現。

國內大家熟知的PRC框架,阿里的HSF和Dubbo(開源)

Dubbo的發展由來

1. 業務規模小

比如早期一個應用Java War包,將所有功能都打包,部署在一個單機伺服器,呼叫介面也比較方便,不涉及到任何分散式場景。

如何從0到1設計一個類Dubbo的RPC框架-mikechen的網際網路架構

2.業務規模變大

隨著業務的快速發展,業務越來越多、子系統也越來越多時。比如:淘寶的交易系統、商品系統、使用者系統、評價系統…上百個系統的出現。

如何從0到1設計一個類Dubbo的RPC框架-mikechen的網際網路架構

系統變得越來越複雜,業務程式碼依然耦合在一起。比如最早期的淘寶denali工程,包含所有業務系統的程式碼,就僅打包部署都需要很長的時間。

並且,隨著每個業務線的快速發展,業務程式碼耦合在一起,上線後出現問題急需要回滾程式碼,拉分支、大量的程式碼merge工作,這個過程極其痛苦。

這個時候,你會發現技術已經成了業務的瓶頸,急需把業務單獨抽離出來,各自單獨部署。

3.Dubbo和HSF的出現

應用系統一旦涉及到拆分部署,問題就來了,急需一種高效的應用程式間的通訊手段來完成這種需求,這就會涉及到分散式遠端呼叫

於是,淘寶就把denali按照業務為單位拆分成了類似這樣的系統:UM(UserManger)、SM(ShopManager)..等等幾十個工程程式碼。

再按照業務為單位,把所有呼叫相關的介面以業務為單元進行拆分:UIC(使用者中心服務)、SIC(店鋪中心服務)…等等以業務為單位叢集部署,按照業務提供服務。

如何從0到1設計一個類Dubbo的RPC框架-mikechen的網際網路架構

所以,RPC的框架來了,阿里內部使用HSF,以及開源的RPC 框架:Dubbo。

RPC框架的核心設計

前面mikechen提到了RPC的核心目標:主要是解決分散式系統中服務之間的呼叫問題。

其實,走到這一步涉及的知識體系非常的多:要求對通訊、遠端呼叫、訊息機制等有深入的理解和掌握,要求的都是從理論、硬體級、作業系統級以及所採用的語言的實現都有清楚的理解。

1.RPC框架三個核心角色

如何從0到1設計一個類Dubbo的RPC框架-mikechen的網際網路架構

1)服務提供者(Server)

對外提供後臺服務,將自己的服務資訊,註冊到註冊中心

2)註冊中心(Registry)

用於服務端註冊遠端服務以及客戶端發現服務。

目前主要的註冊中心可以藉由 zookeeper,eureka,consul,etcd 等開源框架實現。

比如:阿里的Dubbo就是採用zookeeper實現註冊中心。

3)服務消費者(Client)

從註冊中心獲取遠端服務的註冊資訊,然後進行遠端過程呼叫。

2.RPC遠端呼叫過程

如何從0到1設計一個類Dubbo的RPC框架-mikechen的網際網路架構

1)服務呼叫方(client)呼叫以本地呼叫方式呼叫服務;

2)client stub接收到呼叫後負責將方法、引數等組裝成能夠進行網路傳輸的訊息體;在Java裡就是序列化的過程

3)client stub找到服務地址,並將訊息通過網路傳送到服務端;

4)server stub收到訊息後進行解碼,在Java裡就是反序列化的過程;

5)server stub根據解碼結果呼叫本地的服務;

6)本地服務執行處理邏輯;

7)本地服務將結果返回給server stub;

8)server stub將返回結果打包成訊息,Java裡的序列化;

9)server stub將打包後的訊息通過網路併傳送至消費方

10)client stub接收到訊息,並進行解碼, Java裡的反序列化;

11)服務呼叫方(client)得到最終結果。

RPC框架的目標就是要2~10這些步驟都封裝起來。

RPC框架涉及技術

1.建立通訊

首先,要解決通訊的問題,主要是通過在客戶端和伺服器之間建立TCP連線,遠端過程呼叫的所有交換的資料都在這個連線裡傳輸。

2.服務定址

1)服務註冊

首先需要把服務註冊到服務中心。其實就是在註冊中心進行一個登記,註冊中心儲存了該服務的IP、埠、呼叫方式(協議、序列化方式)等。在zookeeper中,進行服務註冊,實際上就是在zookeeper中建立了一個znode節點,該節點儲存了上面所說的服務資訊。

2)服務發現

服務消費者在第一次呼叫服務時,會通過註冊中心找到相應的服務的IP地址列表,並快取到本地,以供後續使用。當消費者呼叫服務時,不會再去請求註冊中心,而是直接通過負載均衡演算法從IP列表中取一個服務提供者的伺服器呼叫服務。

3)註冊服務

可靠的定址方式(主要是提供服務的發現)是RPC的實現基石,比如可以zookeeper來實現註冊服務等等。

如何從0到1設計一個類Dubbo的RPC框架-mikechen的網際網路架構
  •  服務提供者啟動後主動向服務(註冊)中心序號產生器器ip、埠以及提供的服務列表。
  •  服務消費者啟動時向服務(註冊)中心獲取服務提供方地址列表,可實現軟負載均衡和Failover。
  •  提供者需要定時向註冊中心傳送心跳,一段時間未收到來自提供者的心跳後,認為提供者已經停止服務,從註冊中心上摘取掉對應的服務等等。

3.網路傳輸

資料傳輸採用什麼協議,資料該如何序列化和反序列化

4.NIO通訊

當前很多RPC框架都直接基於netty這一IO通訊框架,比如阿里巴巴的HSF、dubbo,Hadoop Avro,推薦使用Netty 作為底層通訊框架。

5.服務呼叫

比如:B機器進行本地呼叫(通過代理Proxy)之後得到了返回值,此時還需要再把返回值傳送回A機器,同樣也需要經過序列化操作,然後再經過網路傳輸將二進位制資料傳送回A機器,而當A機器接收到這些返回值之後,則再次進行反序列化操作

總之,要實現一個RPC不算難,難的是實現一個高效能高可靠的RPC框架,如果還想更加深入瞭解請檢視Dubbo原始碼剖析,看看Dubbo是如何來解決這些難題。

 

關於作者:mikechen,十餘年BAT架構經驗,資深技術專家,曾任職阿里、淘寶、百度。

關注作者公眾號:回覆【架構】,即可檢視mikechen網際網路架構原創的300期+BAT架構技術系列文章與1000+大廠面試題答案合集

相關文章