JavaGuide知識點整理——Dubbo基礎面試題總結

Dubbo基礎

什麼是Dubbo?

Dubbo是Apache下的,一款高性能,輕量級,開源的java RPC框架。
根據Dubbo官方文檔的介紹,Dubbo提供了溜達核心能力:

  1. 面向接口代理的高性能RPC調用
  2. 智能容錯和負載均衡
  3. 服務自動擴展能力
  4. 高度可擴展能力
  5. 運行期流量調度
  6. 可視化的服務治理與運維

    簡單來說,就是Dubbo不光可以幫助我們調用遠程服務,還提供了一些其它開箱即用的功能,比如說智能負載均衡。

爲什麼要用Dubbo?

隨着互聯網的發展,網絡的規模越來越大,用戶數量越來越多。單一應用的架構,垂直應用架構無法滿足我們的需求,這個時候分佈式服務架構就誕生了。
分佈式服務架構下,系統被拆分成不同的服務,比如短信服務,安全服務,每個服務都獨立提供系統的某個核心功能。
實際上Java中的RPC框架也有好幾個,比如Java RMI,Hession等。但是我們爲什麼選擇Dubbo呢?
因爲Java RMI,Hession雖然也能實現遠程調用,但是更適合兩個服務之間相互調用。因爲我工作以來就開始用dubbo,所以爲了這篇筆記特意去搭了以上兩個框架的demo,下面附上一個我覺得寫的比較好的教程:Java常用的RPC框架-RMI,hessian,dubbo
大家去看下大概就能懂這兩個框架的原理,其實就是最基本框的RPC封裝。而且功能很少,只是單純的暴露和引用遠程服務。而且註冊中心還是很直觀的實現。相比於Dubbo的可視化註冊中心,負載均衡,服務監控等就迫在眉睫了。所以說Dubbo更受分佈式系統的青睞(相比於RMI和Hession)。

Dubbo幫助我們解決了什麼問題?

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

分佈式基礎

什麼是分佈式?

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

爲什麼要分佈式?

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

Dubbo架構

Dubbo架構中的核心角色有哪些?


上述節點簡單介紹以及他們之間的關係:

  • Container:服務運行容器,負責加載,運行服務提供者。
  • Provider:暴露服務的服務提供方,會向註冊中心註冊自己提供的服務。
  • Consumer:調用遠程服務的服務消費方,會向註冊中心訂閱自己所需的服務。
  • Registry:服務註冊與發現的註冊中心。註冊中心會返回服務提供者地址列表給消費者。
  • Monitor:統計服務的調用次數和調用時間的監控中心。服務消費者和提供者會定時發送統計數據到監控中心。

Dubbo中的Invoker概念是什麼?

Invoker是Dubbo領域模型中非常重要的一個概念。簡單來說就是Dubbo對遠程調用的抽象:



按照Dubbo官方的話來說,Invoker分爲:

  • 服務提供Invoker
  • 服務消費Invoker

假如我們需要調用一個遠程方法,我們需要動態代理來屏蔽遠程調用的細節。我們屏蔽掉的這些細節就依賴對應的Invoker實現,Invoker實現了真正的遠程服務調用。下面有一篇文章我覺得講的比較好,大家可以看看:深入理解Dubbo核心模型Invoker

Dubbo的工作原理

下圖是Dubbo的整體設計,從下到上分爲十層,各層單項依賴。


  • Service服務層:這個就比較簡單了,就是我們具體的代碼邏輯,其實也算不得是Dubbo的,不多說了。
  • config配置層:Dubbo相關的配置,支持代碼配置,同時也支持基於Spring來做配置。以ServiceConfig,ReferenceConfig爲中心。
  • proxy服務代理層:調用遠程方法像調用本地方法一樣簡單的一個關鍵,真實調用過程依賴代理類,以ServiceProxy爲中心。
  • registry註冊中心層:封裝服務地址的註冊與發現。
  • cluster路由層:封裝多個提供者的路由以及負載均衡,並橋接註冊中心,以Invoker爲中心。
  • monitor監控層:RPC調用次數和調用時間監控。以Statistics爲中心。
  • protocal遠程調用層:封裝RPC調用,以Invocation,Result爲中心。
  • exchange信息交換層:封裝請求響應模式,同步轉異步,以Request,Reponse爲中心。
  • transport網絡傳輸層:抽象mina和netty爲統一接口,以Message爲中心。
  • serialize數據序列化層:對需要在網絡傳輸的數據進行序列化。

Dubbo的SPI機制是什麼?如何讓擴展Dubbo中的默認實現?

SPI(Service Provider Interface)機制被大量用在開源項目中,它可以幫我們動態尋找服務/功能的實現。
SPI的具體原理是這樣的:我們將接口的實現類放在配置文件裏,在程序運行過程中讀取配置文件,通過反射加載實現類。這樣我們可以在運行的時候,動態替換接口的實現類。和IOC的解耦思想是類似的。
java本身就提供了SPI機制的實現,不過dubbo沒有直接用,而是對java原生的spi機制進行了增強,以便更好的滿足自己的需求。
如何擴展Dubb中的默認實現呢?
比如說我們想要實現自己的負載均衡策略,可以創建對應的實現類xxLoadBalance實現LoadBalance接口或者AbstractLoadBalance類。
然後我們可以將這個實現類的路徑寫入到resources目錄下的META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance文件中即可。
其實dubbo還支持很多可供擴展的選擇,我們可以去dubbo開發手冊中查看:https://cn.dubbo.apache.org/zh/docs3-v2/java-sdk/reference-manual/spi/description/

關於Dubbo的一些小問題

  • 註冊中心的作用是什麼?
    註冊中心負責服務地址的註冊與查找,相當於目錄服務,服務提供者和消費者只在啓動時與註冊中心交互。
  • 服務提供者宕機後,註冊中心會做什麼?
    註冊中心會立即推送事件通知消費者。
  • 監控中心的作用呢?
    監控中心負責統計各服務調用次數,調用時間等。
  • 註冊中心和監控中心都宕機的話,服務都會掛掉麼?
    不會,兩者都宕機也不影響已運行的提供者和消費者。消費者在本地緩存了提供者列表。註冊中心和監控中心都是可選的,服務消費者可以直連服務提供者。

Dubbo的負載均衡策略

什麼是負載均衡?

假如我們系統訪問量特別大,我們將這個服務部署在了多臺服務器上,當客戶端發生請求的時候,多臺服務器都可以處理這個請求。那麼如何選擇處理該請求的服務器就很關鍵。負載均衡就是爲了避免請求分配不合理而出現的。

Dubbo提供的負載均衡策略有哪些?

在集羣負載均衡的時候,Dubbo提供了多種均衡策略。默認是random隨機調用。我們還可以自行擴展負載均衡策略。下面是dubbo提供的幾種策略。

  • RandomLoadBalance
    根據權重隨機選擇,這是Dubbo默認採用的一種負載均衡策略。
    這個實現原理非常簡單,比如說權重滿份100,S1權重12,S2權重22,S3權重76.那麼就生成一個0-100的隨機數。前小於12就取S1,12到22之間就取S2,22到100之間就取S3。

  • LeastActiveLoadBalance
    這個直接說原理:每一個服務提供者對應一個活躍數。這個活躍數初始值爲0.收到請求活躍數+1.處理完請求活躍數-1.因此,Dubbo會優先把請求給活躍數最小的服務提供者處理。如果多個提供者活躍數相同則再走一遍RandomLoadBalance。

  • ConsistentHashLoadBalance
    一致性hash負載均衡策略。ConsistentHashLoadBalance中沒有權重的概念。具體哪個服務提供者處理請求是由請求的參數決定的。也就是說相同的參數的請求總是發到同一個服務提供者上。

  • RoundRobinLoadBalance
    加權輪詢負載均衡。簡單可以理解成權重隨機的公平版。既然是基礎的權重比例。只不過這次不隨機獲取了,而是從前到後順序來。

Dubbo的序列化協議

Dubbo支持多種序列化方式,比如jdk自帶的序列化,hessian2,json,kryo,FST之類的。默認使用的是hessian2.
一般我們不會直接使用jdk自帶的序列化方式,主要原因有兩個:

  1. 不支持跨語言調用:如果調用的是其他語言開發的服務就不支持了。
  2. 性能差:相比於其它序列化框架性能更低,主要原因是序列化之後的字節數組體積較大,導致傳輸成本大。

JSON序列化由於性能問題,我們一般也不會考慮使用。
而Protostuff,ProtoBuf,hessian2這些都是跨語言的序列化方式,如果有跨語言需求的話可以考慮使用。
Kryo和FST是Dubbo後來才引入的,性能比較好,不過這兩個都專門針對java語言的。Dubbo官網的一篇文章提到過推薦使用Kryo作爲生產環境的序列化方式。

本篇筆記就到這裏,反正大部分都是八股文,如果對你有所幫助就點個喜歡點個關注吧,也希望大家工作順順利利,身體健健康康!

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