關於 Dubbo 的重要入門知識點總結

  • 2019 年 10 月 6 日
  • 筆記

Dubbo 官網:http://dubbo.apache.org/zh-cn/index.html

Dubbo 中文文檔:http://dubbo.apache.org/zh-cn/index.html

目錄:

  • 一 重要的概念
    • 1.1 什麼是 Dubbo?
    • 1.2 什麼是 RPC?RPC原理是什麼?
    • 1.3 為什麼要用 Dubbo?
    • 1.4 什麼是分佈式?
    • 1.5 為什麼要分佈式?
  • 二 Dubbo 的架構
    • 2.1 Dubbo 的架構圖解
    • 2.2 Dubbo 工作原理
  • 三 Dubbo 的負載均衡策略
    • ‍3.1 先來解釋一下什麼是負載均衡
    • 3.2 再來看看 Dubbo 提供的負載均衡策略‍
      • 3.2.1 Random LoadBalance(默認,基於權重的隨機負載均衡機制)
      • 3.2.2 RoundRobin LoadBalance(不推薦,基於權重的輪詢負載均衡機制)
      • 3.2.3 LeastActive LoadBalance
      • 3.2.4 ConsistentHash LoadBalance
    • 3.3 配置方式
  • 四 zookeeper宕機與dubbo直連的情況

一 重要的概念

1.1 什麼是 Dubbo?

Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、輕量級的開源Java RPC 框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。簡單來說 Dubbo 是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。

Dubbo 目前已經有接近 23k 的 Star ,Dubbo的Github 地址:https://github.com/apache/incubator-dubbo。另外,在開源中國舉行的2018年度最受歡迎中國開源軟件這個活動的評選中,Dubbo 更是憑藉其超高人氣僅次於 vue.js 和 ECharts 獲得第三名的好成績。

Dubbo 是由阿里開源,後來加入了 Apache 。正式由於 Dubbo 的出現,才使得越來越多的公司開始使用以及接受分佈式架構。

除此之外,Apache Dubbo Ecosystem 是圍繞 Apache Dubbo 打造的微服務生態,是經過生產驗證的微服務的最佳實踐組合。在阿里巴巴的微服務解決方案中,Dubbo、Nacos 和 Sentinel,以及後續將開源的微服務組件,都是 Dubbo EcoSystem 的一部分。阿里後續也會將 Dubbo EcoSystem 集成到 Spring Cloud 的生態中。

我們上面說了 Dubbo 實際上是 RPC 框架,那麼什麼是 RPC呢?

1.2 什麼是 RPC?RPC原理是什麼?

什麼是 RPC?

RPC(Remote Procedure Call)—遠程過程調用,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。比如兩個不同的服務A,B部署在兩台不同的機器上,那麼服務 A 如果想要調用服務 B 中的某個方法該怎麼辦呢?使用 HTTP請求 當然可以,但是可能會比較慢而且一些優化做的並不好。RPC 的出現就是為了解決這個問題。

RPC原理是什麼?

我這裡這是簡單的提一下。詳細內容可以查看下面這篇文章:

http://www.importnew.com/22003.html

  1. 服務消費方(client)調用以本地調用方式調用服務;
  2. client stub接收到調用後負責將方法、參數等組裝成能夠進行網絡傳輸的消息體;
  3. client stub找到服務地址,並將消息發送到服務端;
  4. server stub收到消息後進行解碼;
  5. server stub根據解碼結果調用本地的服務;
  6. 本地服務執行並將結果返回給server stub;
  7. server stub將返回結果打包成消息並發送至消費方;
  8. client stub接收到消息,並進行解碼;
  9. 服務消費方得到最終結果。

下面再貼一個網上的時序圖:

說了這麼多,我們為什麼要用 Dubbo 呢?

1.3 為什麼要用 Dubbo?

Dubbo 的誕生和 SOA 分佈式架構的流行有着莫大的關係。SOA 面向服務的架構(Service Oriented Architecture),也就是把工程按照業務邏輯拆分成服務層、表現層兩個工程。服務層中包含業務邏輯,只需要對外提供服務即可。表現層只需要處理和頁面的交互,業務邏輯都是調用服務層的服務來實現。SOA架構中有兩個主要角色:服務提供者(Provider)和服務使用者(Consumer)。

如果你要開發分佈式程序,你也可以直接基於 HTTP 接口進行通信,但是為什麼要用 Dubbo呢?

我覺得主要可以從 Dubbo 提供的下面四點特性來說為什麼要用 Dubbo:

  1. 負載均衡——同一個服務部署在不同的機器時該調用那一台機器上的服務
  2. 服務調用鏈路生成——隨着系統的發展,服務越來越多,服務間依賴關係變得錯蹤複雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關係。Dubbo 可以為我們解決服務之間互相是如何調用的。
  3. 服務訪問壓力以及時長統計、資源調度和治理——基於訪問壓力實時管理集群容量,提高集群利用率。
  4. 服務降級——某個服務掛掉之後調用備用服務

另外,Dubbo 除了能夠應用在分佈式系統中,也可以應用在現在比較火的微服務系統中。不過,由於 Spring Cloud 在微服務中應用更加廣泛,所以,我覺得一般我們提 Dubbo 的話,大部分是分佈式系統的情況。

我們剛剛提到了分佈式這個概念,下面再給大家介紹一下什麼是分佈式?為什麼要分佈式?

1.4 什麼是分佈式?

分佈式或者說 SOA 分佈式重要的就是面向服務,說簡單的分佈式就是我們把整個系統拆分成不同的服務然後將這些服務放在不同的服務器上減輕單體服務的壓力提高並發量和性能。比如電商系統可以簡單地拆分成訂單系統、商品系統、登錄系統等等,拆分之後的每個服務可以部署在不同的機器上,如果某一個服務的訪問量比較大的話也可以將這個服務同時部署在多台機器上。

1.5 為什麼要分佈式?

從開發角度來講單體應用的代碼都集中在一起,而分佈式系統的代碼根據業務被拆分。所以,每個團隊可以負責一個服務的開發,這樣提升了開發效率。另外,代碼根據業務拆分之後更加便於維護和擴展。

另外,我覺得將系統拆分成分佈式之後不光便於系統擴展和維護,更能提高整個系統的性能。你想一想嘛?把整個系統拆分成不同的服務/系統,然後每個服務/系統 單獨部署在一台服務器上,是不是很大程度上提高了系統性能呢?

二 Dubbo 的架構

2.1 Dubbo 的架構圖解

上述節點簡單說明:

  • Provider: 暴露服務的服務提供方
  • Consumer: 調用遠程服務的服務消費方
  • Registry: 服務註冊與發現的註冊中心
  • Monitor: 統計服務的調用次數和調用時間的監控中心
  • Container: 服務運行容器

調用關係說明:

  1. 服務容器負責啟動,加載,運行服務提供者。
  2. 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
  3. 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
  4. 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
  5. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
  6. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。

重要知識點總結:

  • 註冊中心負責服務地址的註冊與查找,相當於目錄服務,服務提供者和消費者只在啟動時與註冊中心交互,註冊中心不轉發請求,壓力較小
  • 監控中心負責統計各服務調用次數,調用時間等,統計先在內存匯總後每分鐘一次發送到監控中心服務器,並以報表展示
  • 註冊中心,服務提供者,服務消費者三者之間均為長連接,監控中心除外
  • 註冊中心通過長連接感知服務提供者的存在,服務提供者宕機,註冊中心將立即推送事件通知消費者
  • 註冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表
  • 註冊中心和監控中心都是可選的,服務消費者可以直連服務提供者
  • 服務提供者無狀態,任意一台宕掉後,不影響使用
  • 服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復

2.2 Dubbo 工作原理

圖中從下至上分為十層,各層均為單向依賴,右邊的黑色箭頭代表層之間的依賴關係,每一層都可以剝離上層被複用,其中,Service 和 Config 層為 API,其它各層均為 SPI。

各層說明

  • 第一層:service層,接口層,給服務提供者和消費者來實現的
  • 第二層:config層,配置層,主要是對dubbo進行各種配置的
  • 第三層:proxy層,服務接口透明代理,生成服務的客戶端 Stub 和服務器端 Skeleton
  • 第四層:registry層,服務註冊層,負責服務的註冊與發現
  • 第五層:cluster層,集群層,封裝多個服務提供者的路由以及負載均衡,將多個實例組合成一個服務
  • 第六層:monitor層,監控層,對rpc接口的調用次數和調用時間進行監控
  • 第七層:protocol層,遠程調用層,封裝rpc調用
  • 第八層:exchange層,信息交換層,封裝請求響應模式,同步轉異步
  • 第九層:transport層,網絡傳輸層,抽象mina和netty為統一接口
  • 第十層:serialize層,數據序列化層。網絡傳輸需要。

三 Dubbo 的負載均衡策略

3.1 先來解釋一下什麼是負載均衡

先來個官方的解釋。

維基百科對負載均衡的定義:負載均衡改善了跨多個計算資源(例如計算機,計算機集群,網絡鏈接,中央處理單元或磁盤驅動的的工作負載分佈。負載平衡旨在優化資源使用,最大化吞吐量,最小化響應時間,並避免任何單個資源的過載。使用具有負載平衡而不是單個組件的多個組件可以通過冗餘提高可靠性和可用性。負載平衡通常涉及專用軟件或硬件

上面講的大家可能不太好理解,再用通俗的話給大家說一下。

比如我們的系統中的某個服務的訪問量特別大,我們將這個服務部署在了多台服務器上,當客戶端發起請求的時候,多台服務器都可以處理這個請求。那麼,如何正確選擇處理該請求的服務器就很關鍵。假如,你就要一台服務器來處理該服務的請求,那該服務部署在多台服務器的意義就不復存在了。負載均衡就是為了避免單個服務器響應同一請求,容易造成服務器宕機、崩潰等問題,我們從負載均衡的這四個字就能明顯感受到它的意義。

3.2 再來看看 Dubbo 提供的負載均衡策略

在集群負載均衡時,Dubbo 提供了多種均衡策略,默認為 random 隨機調用。可以自行擴展負載均衡策略,參見:負載均衡擴展。

備註:下面的圖片來自於:尚硅谷2018Dubbo 視頻。

3.2.1 Random LoadBalance(默認,基於權重的隨機負載均衡機制)

  • 隨機,按權重設置隨機概率。
  • 在一個截面上碰撞的概率高,但調用量越大分佈越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者權重。

3.2.2 RoundRobin LoadBalance(不推薦,基於權重的輪詢負載均衡機制)

  • 輪循,按公約後的權重設置輪循比率。
  • 存在慢的提供者累積請求的問題,比如:第二台機器很慢,但沒掛,當請求調到第二台時就卡在那,久而久之,所有請求都卡在調到第二台上。

3.2.3 LeastActive LoadBalance

  • 最少活躍調用數,相同活躍數的隨機,活躍數指調用前後計數差。
  • 使慢的提供者收到更少請求,因為越慢的提供者的調用前後計數差會越大。

3.2.4 ConsistentHash LoadBalance

  • 一致性 Hash,相同參數的請求總是發到同一提供者。(如果你需要的不是隨機負載均衡,是要一類請求都到一個節點,那就走這個一致性hash策略。)
  • 當某一台提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。
  • 算法參見:http://en.wikipedia.org/wiki/Consistent_hashing
  • 缺省只對第一個參數 Hash,如果要修改,請配置 <dubbo:parameterkey="hash.arguments"value="0,1"/>
  • 缺省用 160 份虛擬節點,如果要修改,請配置 <dubbo:parameterkey="hash.nodes"value="320"/>

3.3 配置方式

xml 配置方式

服務端服務級別

<dubbo:service interface="..." loadbalance="roundrobin" />

客戶端服務級別

<dubbo:reference interface="..." loadbalance="roundrobin" />

服務端方法級別

<dubbo:service interface="...">      <dubbo:method name="..." loadbalance="roundrobin"/>  </dubbo:service>

客戶端方法級別

<dubbo:reference interface="...">      <dubbo:method name="..." loadbalance="roundrobin"/>  </dubbo:reference>

註解配置方式:

消費方基於基於註解的服務級別配置方式:

@Reference(loadbalance = "roundrobin")  HelloService helloService;

四 zookeeper宕機與dubbo直連的情況

zookeeper宕機與dubbo直連的情況在面試中可能會被經常問到,所以要引起重視。

在實際生產中,假如zookeeper註冊中心宕掉,一段時間內服務消費方還是能夠調用提供方的服務的,實際上它使用的本地緩存進行通訊,這只是dubbo健壯性的一種提現。

dubbo的健壯性表現:

  1. 監控中心宕掉不影響使用,只是丟失部分採樣數據
  2. 數據庫宕掉後,註冊中心仍能通過緩存提供服務列表查詢,但不能註冊新服務
  3. 註冊中心對等集群,任意一台宕掉後,將自動切換到另一台
  4. 註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地緩存通訊
  5. 服務提供者無狀態,任意一台宕掉後,不影響使用
  6. 服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復

我們前面提到過:註冊中心負責服務地址的註冊與查找,相當於目錄服務,服務提供者和消費者只在啟動時與註冊中心交互,註冊中心不轉發請求,壓力較小。所以,我們可以完全可以繞過註冊中心——採用 dubbo 直連 ,即在服務消費方配置服務提供方的位置信息。

xml配置方式:

<dubbo:reference id="userService" interface="com.zang.gmall.service.UserService" url="dubbo://localhost:20880" />

註解方式:

@Reference(url = "127.0.0.1:20880")   HelloService helloService;