dubbo的原理以及面試題分析


1.什么是dubbo?
Dubbo就是SOA服務治理方案的核心框架。用於分布式調用,其重點在於分布式的治理。

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

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

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

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

3.Dubbo組件角色

 

 

 

Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務注冊與發現的注冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
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 提供了聲明式緩存,用於加速熱門數據的訪問速度,以減少用戶加緩存的工作量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM