dubbo的原理以及面試題分析

1.什麼是dubbo?

Dubbo就是SOA服務治理方案的核心框架。用於分佈式調用,其重點在於分佈式的治理。

Dubbo是Alibaba開源的分佈式服務框架,它最大的特點是按照分層的方式來架構,使用這種方式可以使各個層之間解耦合(或者最大限度地鬆耦合),比如表現層和業務層就需要解耦合。

從面向服務的角度來看,Dubbo採用的是一種非常簡單的模型,要麼是提供方提供服務,要麼是消費方消費服務,所以基於這一點可以抽象出服務提供方(Provider)和服務消費方(Consumer)兩個角色。

除了以上兩個角色,它還有註冊中心和監控中心。它可以通過註冊中心對服務進行註冊和訂閱;可以通過監控中心對服務進行監控,這樣的話,就可以知道哪些服務使用率高、哪些服務使用率低。對使用率高的服務增加機器,對使用率低的服務減少機器,達到合理分配資源的目的。

2.Dubbo核心功能

1、Remoting:遠程通訊,提供對多種NIO框架抽象封裝,包括“同步轉異步”和“請求-響應”模式的信息交換方式。
2、Cluster:服務框架,提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集羣支持。
3、Registry:服務註冊,基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。

3.Dubbo組件角色

在這裏插入圖片描述

  1. Provider: 暴露服務的服務提供方。
  2. Consumer: 調用遠程服務的服務消費方。
  3. Registry: 服務註冊與發現的註冊中心。
  4. Monitor: 統計服務的調用次調和調用時間的監控中心。
  5. Container: 服務運行容器,常見的容器有Spring容器。

調用關係說明:

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

4.Dubbo總體架構

上面介紹給出的都是抽象層面的組件關係,可以說是縱向的以服務模型的組件分析,其實Dubbo最大的特點是按照分層的方式來架構,使用這種方式可以使各個層之間解耦合(或者最大限度地鬆耦合)。所以,我們橫向以分層的方式來看下Dubbo的架構,如圖所示:
在這裏插入圖片描述

Dubbo框架設計一共劃分了10個層,而最上面的Service層是留給實際想要使用Dubbo開發分佈式服務的開發者實現業務邏輯的接口層。圖中左邊淡藍背景的爲服務消費方使用的接口,右邊淡綠色背景的爲服務提供方使用的接口, 位於中軸線上的爲雙方都用到的接口。

下面,結合Dubbo官方文檔,我們分別理解一下框架分層架構中,各個層次的設計要點:

服務接口層(Service):
與實際業務邏輯相關的,根據服務提供方和服務消費方的 業務設計對應的接口和實現。
***配置層(Config)***:
對外配置接口,以ServiceConfig和ReferenceConfig爲中心,可以直接new配置類,也可以通過Spring解析配置生成配置類。
服務代理層(Proxy):
服務接口透明代理,生成服務的客戶端Stub和服務器端Skeleton,以ServiceProxy爲中心,擴展接口爲ProxyFactory。
服務註冊層(Registry):
封裝服務地址的註冊與發現,以服務URL爲中心,擴展接口爲RegistryFactory、Registry和RegistryService。可能沒有服務註冊中心,此時服務提供方直接暴露服務。
集羣層(Cluster):
封裝多個提供者的路由及負載均衡,並橋接註冊中心,以Invoker爲中心,擴展接口爲Cluster、Directory、Router和LoadBalance。將多個服務提供方組合爲一個服務提供方,實現對服務消費方來透明,只需要與一個服務提供方進行交互。
監控層(Monitor):
RPC調用次數和調用時間監控,以Statistics爲中心,擴展接口爲MonitorFactory、Monitor和MonitorService。
遠程調用層(Protocol):
封將RPC調用,以Invocation和Result爲中心,擴展接口爲Protocol、Invoker和Exporter。Protocol是服務域,它是Invoker暴露和引用的主功能入口,它負責Invoker的生命週期管理。Invoker是實體域,它是Dubbo的核心模型,其它模型都向它靠擾,或轉換成它,它代表一個可執行體,可向它發起invoke調用,它有可能是一個本地的實現,也可能是一個遠程的實現,也可能一個集羣實現。
信息交換層(Exchange):
封裝請求響應模式,同步轉異步,以Request和Response爲中心,擴展接口爲Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
網絡傳輸層(Transport):
抽象mina和netty爲統一接口,以Message爲中心,擴展接口爲Channel、Transporter、Client、Server和Codec。
數據序列化層(Serialize):
可複用的一些工具,擴展接口爲Serialization、 ObjectInput、ObjectOutput和ThreadPool。
從上圖可以看出,Dubbo對於服務提供方和服務消費方,從框架的10層中分別提供了各自需要關心和擴展的接口,構建整個服務生態系統(服務提供方和服務消費方本身就是一個以服務爲中心的)。

5.根據官方提供的,對於上述各層之間關係的描述,如下所示:

1、在RPC中,Protocol是核心層,也就是只要有Protocol + Invoker + Exporter就可以完成非透明的RPC調用,然後在Invoker的主過程上Filter攔截點。

2、圖中的Consumer和Provider是抽象概念,只是想讓看圖者更直觀的瞭解哪些分類屬於客戶端與服務器端,不用Client和Server的原因是Dubbo在很多場景下都使用Provider、Consumer、Registry、Monitor劃分邏輯拓普節點,保持概念統一。

3、而Cluster是外圍概念,所以Cluster的目的是將多個Invoker僞裝成一個Invoker,這樣其它人只要關注Protocol層Invoker即可,加上Cluster或者去掉Cluster對其它層都不會造成影響,因爲只有一個提供者時,是不需要Cluster的。

4、Proxy層封裝了所有接口的透明化代理,而在其它層都以Invoker爲中心,只有到了暴露給用戶使用時,才用Proxy將Invoker轉成接口,或將接口實現轉成Invoker,也就是去掉Proxy層RPC是可以Run的,只是不那麼透明,不那麼看起來像調本地服務一樣調遠程服務。

5、而Remoting實現是Dubbo協議的實現,如果你選擇RMI協議,整個Remoting都不會用上,Remoting內部再劃爲Transport傳輸層和Exchange信息交換層,Transport層只負責單向消息傳輸,是對Mina、Netty、Grizzly的抽象,它也可以擴展UDP傳輸,而Exchange層是在傳輸層之上封裝了Request-Response語義。

6、Registry和Monitor實際上不算一層,而是一個獨立的節點,只是爲了全局概覽,用層的方式畫在一起。

6.服務調用流程

在這裏插入圖片描述

7.連接方式

1、直連:

不通過註冊中心,直接由消費者訪問提供者。
2、集羣:

提供者把服務註冊到註冊中心,然後消費者詢問註冊中心,請求對應的服務需要請求哪個提供者,註冊中心返回結果,消費者根據結果向提供者請求服務。
3、超時和重連機制:

(1)dubbo超時,不會返回結果,直接報異常
(2)配置超時重試次數、超時時間:
<!-- 服務調用超時設置爲5秒,超時不重試--> <dubbo:service interface="com.provider.service.DemoService" ref="demoService" retries="0" timeout="5000"/>
(3)dubbo在調用服務不成功時,默認會重試2次。
Dubbo的路由機制,會把超時的請求路由到其他機器上,而不是本機嘗試,所以 dubbo的重試機器也能一定程度的保證服務的質量。但是如果不合理的配置重試次數,當失敗時會進行重試多次,這樣在某個時間點出現性能問題,調用方再連續重複調用,系統請求變爲正常值的retries倍,系統壓力會大增,容易引起服務雪崩,需要根據業務情況規劃好如何進行異常處理,何時進行重試。
group及version

8.group及version

1、group:用於對服務進行隔離,這裏可以實現灰度功能的作用。
2、version:當一個接口的實現,出現不兼容升級時,可以用版本號過渡,版本號不同的服務相互間不引用
*

9.面試題剖析

9.1dubbo工作原理

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

工作流程:

1)第一步,provider向註冊中心去註冊
2)第二步,consumer從註冊中心訂閱服務,註冊中心會通知consumer註冊好的服務
3)第三步,consumer調用provider
4)第四步,consumer和provider都異步的通知監控中心

在這裏插入圖片描述

9.2註冊中心掛了可以繼續通信嗎?

可以,因爲剛開始初始化的時候,消費者會將提供者的地址等信息拉取到本地緩存,所以註冊中心掛了可以繼續通信。

9.3Dubbo的執行流程:

項目一啓動,加載配置文件的時候,就會初始化,服務的提供方ServiceProvider就會向註冊中心註冊自己提供的服務,當消費者在啓動時,就會向註冊中心訂閱自己所需要的服務,如果服務提供方有數據變更等,註冊中心將基於長連接的形式推送變更數據給消費者。
默認使用Dubbo協議:
連接個數:單連接
連接方式:長連接
傳輸協議:TCP
傳輸方式:NIO異步傳輸
序列化:Hessian二進制序列化
適用範圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓滿提供者,儘量不要使用dubbo協議傳輸大文件或超大字符串
使用場景:常規遠程服務方法調用
從上面的適用範圍總結,dubbo適合小數據量大併發的服務調用,以及消費者機器遠大於生產者機器數的情況,不適合傳輸大數據量的服務比如文件、視頻等,除非請求量很低。

9.4Dubbo的安全性如何得到保障:
a.在有註冊中心的情況下,可以通過dubbbo admin中的路由規則,來指定固定ip的消費方來訪問
b.在直連的情況下,通過在服務的提供方中設置密碼(令牌)token,消費方需要在消費時也輸入這 個密碼,才能夠正確使用。
Dubbo添加服務ip白名單,防止不法調用

9.5Duubo中如何保證分佈式事務?
一般情況下,我們儘量將需要事務的方法放在一個service中,從而避開分步式事務。
Dubbo底層是基於socket: Socket通信是一個全雙工的方式,如果有多個線程同時進行遠程方法調用,這時建立在client server之間的socket連接上會有很多雙方發送的消息傳遞,前後順序也可能是亂七八糟的,server處理完結果後,將結果消息發送給client,client收到很多消息,怎麼知道哪個消息結果是原先哪個線程調用的?
答:使用一個ID,讓其唯一,然後傳遞給服務端,再服務端又回傳回來,這樣就知道結果是原先哪個線程的了。

9.6Dubbo的心跳機制:
目的:
維持provider和consumer之間的長連接
實現:
dubbo心跳時間heartbeat默認是1s,超過heartbeat時間沒有收到消息,就發送心跳消 息(provider,consumer一樣),如果連着3次(heartbeatTimeout爲heartbeat*3)沒有收到心跳響應,provider會關閉channel,而consumer會進行重連;不論是provider還是consumer的心跳檢測都是通過啓動定時任務的方式實現;

Dubbo的zookeeper做註冊中心,如果註冊中心全部掛掉,發佈者和訂閱者還能通信嗎?
可以通信的,啓動dubbo時,消費者會從zk拉取註冊的生產者的地址接口等數據,緩存在本地。每次調用時,按照本地存儲的地址進行調用;
註冊中心對等集羣,任意一臺宕機後,將會切換到另一臺;註冊中心全部宕機後,服務的提供者和消費者仍能通過本地緩存通訊。服務提供者無狀態,任一臺 宕機後,不影響使用;服務提供者全部宕機,服務消費者會無法使用,並無限次重連等待服務者恢復;
掛掉是不要緊的,但前提是你沒有增加新的服務,如果你要調用新的服務,則是不能辦到的。

9.7爲什麼要用Dubbo?
因爲是阿里開源項目,國內很多互聯網公司都在用,已經經過很多線上考驗。內部使用了 Netty、Zookeeper,保證了高性能高可用性。

使用 Dubbo 可以將核心業務抽取出來,作爲獨立的服務,逐漸形成穩定的服務中心,可用於提高業務複用靈活擴展,使前端應用能更快速的響應多變的市場需求。

下面這張圖解釋,最重要的一點是,分佈式架構可以承受更大規模的併發流量。
在這裏插入圖片描述
以下是 Dubbo 的服務治理圖。

在這裏插入圖片描述

9.8dubbo都支持什麼協議,推薦用哪種?

dubbo://(推薦)

rmi://

hessian://

http://

webservice://

thrift://

memcached://

redis://

rest://

9.9Dubbo需要 Web 容器嗎?

不需要,如果硬要用 Web 容器,只會增加複雜性,也浪費資源。

9.10Dubbo內置了哪幾種服務容器?

Spring Container

Jetty Container

Log4j Container

Dubbo 的服務容器只是一個簡單的 Main 方法,並加載一個簡單的 Spring 容器,用於暴露服務。

9.11Dubbo默認使用什麼註冊中心,還有別的選擇嗎

推薦使用 Zookeeper 作爲註冊中心,還有 Redis、Multicast、Simple 註冊中心,但不推薦。

9.12Dubbo有哪幾種配置方式?

1)Spring 配置方式
2)Java API 配置方式

9.13在 Provider 上可以配置的 Consumer 端的屬性有哪些?

1)timeout:方法調用超時
2)retries:失敗重試次數,默認重試 2 次
3)loadbalance:負載均衡算法,默認隨機
4)actives 消費者端,最大併發調用限制

9.14Dubbo啓動時如果依賴的服務不可用會怎樣?

Dubbo 缺省會在啓動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止 Spring 初始化完成,默認 check=“true”,可以通過 check=“false” 關閉檢查。

9.15Dubbo推薦使用什麼序列化框架,你知道的還有哪些?

推薦使用Hessian序列化,還有Duddo、FastJson、Java自帶序列化。

9.16Dubbo默認使用的是什麼通信框架,還有別的選擇嗎?

Dubbo 默認使用 Netty 框架,也是推薦的選擇,另外內容還集成有Mina、Grizzly。

9.17當一個服務接口有多種實現時怎麼做?

當一個接口有多種實現時,可以用 group 屬性來分組,服務提供方和消費方都指定同一個 group 即可。

9.18服務上線怎麼兼容舊版本?

可以用版本號(version)過渡,多個不同版本的服務註冊到註冊中心,版本號不同的服務相互間不引用。這個和服務分組的概念有一點類似。

9.19Dubbo可以對結果進行緩存嗎?

可以,Dubbo 提供了聲明式緩存,用於加速熱門數據的訪問速度,以減少用戶加緩存的工作量。

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