Java面試被問(wèn)到Dubbo,怎么回答可以得高分?
大家好,我是哪吒。
面試中被問(wèn)到dubbo,我覺(jué)得可以從以下10點(diǎn)著手回答,堪稱(chēng)完美!
Dubbo是一個(gè)高性能的Java RPC框架。RPC是遠(yuǎn)程過(guò)程調(diào)用的縮寫(xiě),其基本思想是:客戶(hù)端像調(diào)用本地方法一樣,通過(guò)網(wǎng)絡(luò)請(qǐng)求調(diào)用遠(yuǎn)程服務(wù)器上的服務(wù)。Dubbo可以幫助我們更方便地構(gòu)建分布式應(yīng)用程序,它具有高效的遠(yuǎn)程調(diào)用、服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)、負(fù)載均衡、容錯(cuò)機(jī)制等眾多特性,是企業(yè)級(jí)應(yīng)用中可靠的基礎(chǔ)架構(gòu)。
一、介紹
1、Dubbo是什么
Dubbo是一種高性能、輕量級(jí)的分布式服務(wù)框架,它的設(shè)計(jì)目標(biāo)是為大規(guī)模分布式應(yīng)用提供支持。
Dubbo由阿里巴巴提供,最初由Alibaba Dubbo Team開(kāi)發(fā),目前已經(jīng)成為Apache基金會(huì)的頂級(jí)項(xiàng)目。Dubbo在國(guó)內(nèi)得到了廣泛的應(yīng)用,像阿里巴巴、京東、美團(tuán)等眾多互聯(lián)網(wǎng)企業(yè)都在使用該框架。
圖片
2、為什么需要Dubbo
在分布式系統(tǒng)中,服務(wù)之間相互依賴(lài)非常復(fù)雜,需要大量的通信和協(xié)調(diào)。Dubbo可以幫助我們更方便地構(gòu)建分布式應(yīng)用程序,它具有高效的遠(yuǎn)程調(diào)用、服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)、負(fù)載均衡、容錯(cuò)機(jī)制等眾多特性。通過(guò)Dubbo,我們可以更方便地實(shí)現(xiàn)服務(wù)治理、服務(wù)調(diào)用鏈追蹤、服務(wù)降級(jí)、服務(wù)熔斷等重要功能。
3、Dubbo的特性
Dubbo最重要的特性包括:
- 高效的遠(yuǎn)程調(diào)用,支持多種傳輸協(xié)議、序列化協(xié)議和集群容錯(cuò)機(jī)制;
- 可擴(kuò)展的服務(wù)自動(dòng)發(fā)現(xiàn),支持多種注冊(cè)中心;
- 豐富的負(fù)載均衡策略,支持輪詢(xún)、隨機(jī)、最少活躍調(diào)用等多種策略;
- 靈活的集群容錯(cuò)機(jī)制,支持多種容錯(cuò)策略;
- 多協(xié)議支持,Dubbo同時(shí)支持dubbo://、http://和hessian://等多種協(xié)議。
二、Dubbo的核心概念
1、暴露Export
Dubbo的暴露和引用是通過(guò)ProviderConfig和ConsumerConfig實(shí)現(xiàn)的。
ProviderConfig是服務(wù)提供者配置類(lèi),可以用于配置服務(wù)的接口、服務(wù)實(shí)現(xiàn)類(lèi)、協(xié)議等,還可以設(shè)置暴露服務(wù)所用的協(xié)議、權(quán)重、端口號(hào)等信息。
ConsumerConfig是服務(wù)消費(fèi)者配置類(lèi),可以用于配置服務(wù)消費(fèi)者所接口、協(xié)議等信息,還可以設(shè)置引用服務(wù)所用的協(xié)議、集群等信息。
圖片
暴露:
- 暴露過(guò)程中,首先需要解析配置,根據(jù)配置中的協(xié)議創(chuàng)建相應(yīng)的協(xié)議實(shí)現(xiàn)。
- 將協(xié)議綁定到指定的 IP 和端口上。
- 將服務(wù)地址信息注冊(cè)到注冊(cè)中心,以供其他調(diào)用者查詢(xún)。
- 通知訂閱者(監(jiān)聽(tīng)器)服務(wù)地址信息的變化。
- 調(diào)用者接收到訂閱者的通知,得知服務(wù)地址信息變化。
- 調(diào)用者通過(guò)網(wǎng)絡(luò)層向提供者發(fā)起調(diào)用請(qǐng)求。
- 提供者處理請(qǐng)求后,返回結(jié)果給調(diào)用者。
2、引用Refer
引用的過(guò)程類(lèi)似,只是方向相反,具體如下:
圖片
引用
- 引用過(guò)程中,同樣需要解析配置,根據(jù)配置中的協(xié)議創(chuàng)建相應(yīng)的協(xié)議實(shí)現(xiàn)。
- 連接到指定的服務(wù)地址。
- 查詢(xún)注冊(cè)中心,獲取對(duì)應(yīng)服務(wù)地址信息。
- 返回服務(wù)地址信息給調(diào)用者。
- 提供者處理調(diào)用請(qǐng)求,返回結(jié)果給調(diào)用者。
- 調(diào)用者接收到結(jié)果,結(jié)束調(diào)用過(guò)程。
3、服務(wù)提供者和服務(wù)消費(fèi)者
Dubbo的服務(wù)提供者是指提供服務(wù)的主體,通常會(huì)暴露自己的服務(wù)接口,并通過(guò)某種協(xié)議提供服務(wù)。而服務(wù)消費(fèi)者是使用服務(wù)的主體,通常會(huì)引用提供者的服務(wù)接口,并通過(guò)某種協(xié)議調(diào)用服務(wù)。
圖片
- 服務(wù)提供者向 Zookeeper 注冊(cè)服務(wù),服務(wù)消費(fèi)者向 Zookeeper 訂閱服務(wù)。
- 服務(wù)消費(fèi)者通過(guò) Zookeeper 獲取服務(wù)提供者的地址信息,然后調(diào)用服務(wù)提供者的服務(wù)。
4、注冊(cè)中心
Dubbo最核心的概念就是注冊(cè)中心,它用于管理服務(wù)提供者的注冊(cè)與發(fā)現(xiàn),使服務(wù)消費(fèi)者能夠動(dòng)態(tài)地發(fā)現(xiàn)和訪問(wèn)服務(wù)提供者。Dubbo支持多種注冊(cè)中心,包括Zookeeper、Redis、Multicast等等,其中Zookeeper是Dubbo默認(rèn)的注冊(cè)中心。
圖片
注冊(cè)中心
- 服務(wù)提供者將自己提供的服務(wù)注冊(cè)到注冊(cè)中心。
- 服務(wù)消費(fèi)者從注冊(cè)中心訂閱所需的服務(wù)列表。
- 注冊(cè)中心返回可用的服務(wù)列表給服務(wù)提供者和服務(wù)消費(fèi)者。
- 服務(wù)消費(fèi)者調(diào)用服務(wù)提供者的服務(wù)。
- 服務(wù)提供者返回服務(wù)結(jié)果給服務(wù)消費(fèi)者。
5、負(fù)載均衡
Dubbo 的負(fù)載均衡是指服務(wù)消費(fèi)者在調(diào)用服務(wù)提供者的時(shí)候,如何從多個(gè)服務(wù)提供者中選擇一個(gè)進(jìn)行調(diào)用。
Dubbo 默認(rèn)提供了多種負(fù)載均衡策略,例如隨機(jī)、輪詢(xún)、最少活躍數(shù)等。服務(wù)消費(fèi)者通過(guò) Dubbo 的負(fù)載均衡模塊,將請(qǐng)求分發(fā)給多個(gè)服務(wù)提供者,然后由負(fù)載均衡模塊根據(jù)選定的負(fù)載均衡策略選擇一個(gè)服務(wù)提供者進(jìn)行調(diào)用,從而達(dá)到分?jǐn)傌?fù)載的效果。
圖片
負(fù)載均衡
在圖中,服務(wù)消費(fèi)者 A 需要調(diào)用一個(gè)服務(wù)提供者,但是有多個(gè)服務(wù)提供者可供選擇,這時(shí)候負(fù)載均衡 B 就發(fā)揮作用了。B 會(huì)根據(jù)負(fù)載均衡策略,選擇一個(gè)服務(wù)提供者進(jìn)行調(diào)用,例如選擇了服務(wù)提供者1 C。如果 C 發(fā)生故障或宕機(jī),B 就會(huì)重新選擇一個(gè)可用的服務(wù)提供者,例如選擇了服務(wù)提供者2 D。這樣,服務(wù)消費(fèi)者 A 就可以通過(guò) Dubbo 的負(fù)載均衡模塊,動(dòng)態(tài)地選擇服務(wù)提供者,從而實(shí)現(xiàn)負(fù)載均衡。
6、集群容錯(cuò)
Dubbo的集群容錯(cuò)是指當(dāng)服務(wù)提供者發(fā)生故障時(shí),Dubbo如何從備選節(jié)點(diǎn)中選擇一個(gè)可用的節(jié)點(diǎn)讓服務(wù)消費(fèi)者訪問(wèn)。Dubbo提供了多種集群容錯(cuò)策略,包括快速失敗、失敗切換、失敗重試等等,可以根據(jù)需求選擇適合的策略。
圖片
集群容錯(cuò)
- Consumer:服務(wù)的消費(fèi)者,發(fā)起服務(wù)調(diào)用的一方。
- Invoker:Dubbo 中的調(diào)用器,將消費(fèi)者的請(qǐng)求轉(zhuǎn)換成可執(zhí)行的任務(wù)并執(zhí)行。
- Cluster:Dubbo 中的集群容錯(cuò)模塊,將多個(gè) Invoker 封裝成一個(gè)集群。
- Failover:Dubbo 集群容錯(cuò)模塊中的容錯(cuò)策略之一,如果某次調(diào)用失敗,會(huì)自動(dòng)切換到下一個(gè) Invoker 進(jìn)行調(diào)用,直到成功為止。
- Failfast:Dubbo 集群容錯(cuò)模塊中的容錯(cuò)策略之一,如果某次調(diào)用失敗,會(huì)立即拋出異常。
- Failsafe:Dubbo 集群容錯(cuò)模塊中的容錯(cuò)策略之一,如果某次調(diào)用失敗,會(huì)記錄下異常,但不會(huì)拋出異常。
- Failback:Dubbo 集群容錯(cuò)模塊中的容錯(cuò)策略之一,如果某次調(diào)用失敗,會(huì)在后臺(tái)異步重試。
- Forking:Dubbo 集群容錯(cuò)模塊中的容錯(cuò)策略之一,將請(qǐng)求并發(fā)調(diào)用多個(gè) Invoker,只要有一個(gè) Invoker 成功返回結(jié)果,就立即返回。
三、Dubbo的架構(gòu)
1、服務(wù)提供者和服務(wù)消費(fèi)者之間的通信流程
在Dubbo中,服務(wù)提供者和服務(wù)消費(fèi)者之間的通信流程較為復(fù)雜,涉及到多個(gè)角色的交互。
下面簡(jiǎn)要介紹Dubbo的通信流程:
- 服務(wù)消費(fèi)者向注冊(cè)中心發(fā)起服務(wù)發(fā)現(xiàn)請(qǐng)求,獲取服務(wù)列表。
- 注冊(cè)中心返回服務(wù)列表給服務(wù)消費(fèi)者。
- 服務(wù)消費(fèi)者根據(jù)負(fù)載均衡策略選擇一個(gè)服務(wù)提供者。
- 服務(wù)提供者返回自身的 IP 地址和端口號(hào)給服務(wù)消費(fèi)者。
- 服務(wù)消費(fèi)者通過(guò)網(wǎng)絡(luò)向服務(wù)提供者發(fā)送請(qǐng)求消息。
- 服務(wù)提供者處理請(qǐng)求并返回響應(yīng)消息給服務(wù)消費(fèi)者。
圖片
dubbo的架構(gòu)
整個(gè)通信流程中,Dubbo使用了類(lèi)似RPC(Remote Procedure Call)的方式進(jìn)行通信,即服務(wù)消費(fèi)者發(fā)送請(qǐng)求給服務(wù)提供者,服務(wù)提供者返回結(jié)果給服務(wù)消費(fèi)者。
Dubbo的主要區(qū)別在于,Dubbo支持多種協(xié)議和序列化機(jī)制,同時(shí)還提供了負(fù)載均衡、集群容錯(cuò)等功能。
2、Dubbo的三層架構(gòu)
Dubbo的三層架構(gòu)包括:
(1)接口層
接口層是Dubbo的核心,它定義了服務(wù)提供者和服務(wù)消費(fèi)者之間的通信接口。在Dubbo中,接口默認(rèn)使用Java接口實(shí)現(xiàn),具有很強(qiáng)的可擴(kuò)展性。
(2)配置層
配置層的作用是通過(guò)配置文件或代碼來(lái)配置Dubbo的各種參數(shù),包括連接參數(shù)、超時(shí)時(shí)間、重試次數(shù)等等。Dubbo支持多種配置方式,包括XML配置、注解配置和屬性配置。
(3)基礎(chǔ)設(shè)施層
基礎(chǔ)設(shè)施層是Dubbo的底層架構(gòu),包括了Dubbo的RPC框架、網(wǎng)絡(luò)通信、序列化和反序列化等實(shí)現(xiàn)細(xì)節(jié)。Dubbo的基礎(chǔ)設(shè)施層具有較高的性能和可定制性。
圖片
Dubbo的三層架構(gòu)
3、Dubbo的擴(kuò)展機(jī)制
Dubbo提供了較為完善的擴(kuò)展機(jī)制,使得開(kāi)發(fā)者可以輕松改變Dubbo的默認(rèn)行為,實(shí)現(xiàn)個(gè)性化定制。
Dubbo的擴(kuò)展機(jī)制主要有三種:
(1)SPI機(jī)制
Dubbo使用了SPI(Service Provider Interface)機(jī)制,開(kāi)發(fā)者可以通過(guò)在class path下提供指定的接口實(shí)現(xiàn)類(lèi)來(lái)替換Dubbo框架默認(rèn)的實(shí)現(xiàn)。在Dubbo中,SPI機(jī)制通過(guò)Java的ServiceLoader實(shí)現(xiàn)。
(2)Adaptive機(jī)制
Dubbo的Adaptive機(jī)制是對(duì)SPI機(jī)制的一種補(bǔ)充,它可以根據(jù)不同的場(chǎng)景自動(dòng)適配最合適的實(shí)現(xiàn)類(lèi)。Adaptive機(jī)制通過(guò)動(dòng)態(tài)生成的代理類(lèi)來(lái)實(shí)現(xiàn)。
(3)Extension機(jī)制
Extension機(jī)制是Dubbo的核心擴(kuò)展機(jī)制,它允許開(kāi)發(fā)者自定義Dubbo的各種插件,包括Protocol、Transport和Serialization等。Extension機(jī)制通過(guò)@SPI和@Adaptive注解實(shí)現(xiàn)。開(kāi)發(fā)者可以通過(guò)實(shí)現(xiàn)指定接口和在注解中指定拓展名,來(lái)實(shí)現(xiàn)自定義插件的加載和使用。
四、Dubbo的配置
1、XML配置
Dubbo的XML配置是最早的配置方式,在配置過(guò)程中需要編寫(xiě)XML文件,指定Dubbo相關(guān)的標(biāo)簽和屬性。其中,最基本的配置是服務(wù)提供者和服務(wù)消費(fèi)者的相關(guān)配置,如下:
<!-- 服務(wù)提供者注冊(cè)到注冊(cè)中心 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- 暴露服務(wù) -->
<dubbo:service interface="com.xxx.xxxService" ref="xxxServiceImpl" timeout="3000" />
<!-- 引用服務(wù) -->
<dubbo:reference interface="com.xxx.xxxService" id="xxxService" timeout="3000" />
在這段XML配置中,我們首先在標(biāo)簽中指定了注冊(cè)中心的地址信息,然后在標(biāo)簽中指定了服務(wù)提供者的接口和實(shí)現(xiàn)類(lèi),以及引用服務(wù)的接口和實(shí)現(xiàn)。timeout屬性用于設(shè)置超時(shí)時(shí)間。
除了服務(wù)提供者和服務(wù)消費(fèi)者的相關(guān)配置外,還有其他相關(guān)的配置。比如,可以使用<dubbo:protocol>標(biāo)簽指定Dubbo使用的協(xié)議類(lèi)型和端口號(hào),同時(shí)也可以在<dubbo:method>標(biāo)簽中為方法單獨(dú)指定超時(shí)時(shí)間等參數(shù)。
2、注解配置
注解配置是一種比較簡(jiǎn)便的配置方式,可以直接在Java代碼中使用注解指定Dubbo相關(guān)的配置信息。使用注解配置時(shí),需要在配置類(lèi)中添加@EnableDubbo注解開(kāi)啟Dubbo相關(guān)功能,示例如下:
@Configuration
@EnableDubbo(scanBasePackages = "com.xxx.service.impl")
public class DubboConfig {
}
其中,scanBasePackages屬性指定了Dubbo掃描的包路徑。然后就可以在服務(wù)提供者和服務(wù)消費(fèi)者的實(shí)現(xiàn)類(lèi)中使用Dubbo提供的注解進(jìn)行配置,示例如下:
@Service(timeout = 3000)
public class XxxServiceImpl implements XxxService {
@Override
public String hello(String name) {
return "Hello " + name;
}
}
對(duì)于服務(wù)消費(fèi)者,則可以使用@DubboReference注解引用服務(wù),示例如下:
@Service
public class XxxConsumer {
@DubboReference(timeout = 3000)
private XxxService xxxService;
public String hello(String name) {
return xxxService.hello(name);
}
}
在這個(gè)例子中,我們使用@DubboReference注解指定了服務(wù)的接口和超時(shí)時(shí)間,然后在XxxConsumer類(lèi)中通過(guò)xxxService調(diào)用服務(wù)。
3、屬性配置
屬性配置是一種比較靈活的配置方式,它允許我們?cè)谂渲梦募卸x屬性,然后在代碼中讀取這些屬性并進(jìn)行相關(guān)操作。使用屬性配置時(shí),我們需要在代碼中創(chuàng)建一個(gè)DubboProperties對(duì)象,并將其中的屬性值通過(guò)@ConfigurationProperties注解注入到該對(duì)象中。示例如下:
@Component
@ConfigurationProperties(prefix = "dubbo")
public class DubboProperties {
private String registryAddress;
// get/set方法省略
}
然后,我們可以使用這個(gè)DubboProperties對(duì)象中定義的屬性配置Dubbo相關(guān)的參數(shù),示例如下:
@Service(timeout = "#{dubboProperties.timeout}")
public class XxxServiceImpl implements XxxService {
@Autowired
private DubboProperties dubboProperties;
@Override
public String hello(String name) {
return "Hello " + name;
}
}
在這個(gè)例子中,我們使用了#{dubboProperties.timeout}的方式,讀取DubboProperties對(duì)象中的timeout屬性來(lái)指定服務(wù)超時(shí)時(shí)間。我們還可以在DubboProviders對(duì)象中定義其他屬性,在需要的地方使用${}的方式讀取這些屬性。
五、Dubbo的高可用與容錯(cuò)
1、服務(wù)降級(jí)
服務(wù)降級(jí)指的是當(dāng)系統(tǒng)出現(xiàn)故障或者異常情況時(shí),系統(tǒng)可以通過(guò)關(guān)閉一些非核心的功能來(lái)保證其他核心功能的正常運(yùn)行。Dubbo提供了服務(wù)降級(jí)的功能,通過(guò)這個(gè)功能,Dubbo可以在某些條件下提供替代方案,比如返回空結(jié)果、返回默認(rèn)結(jié)果等等。
Dubbo的服務(wù)降級(jí)是通過(guò)Mock來(lái)實(shí)現(xiàn)的,Mock可以在接口定義的時(shí)候指定。Dubbo在正常情況下會(huì)使用服務(wù)提供者提供的服務(wù),當(dāng)服務(wù)提供者出現(xiàn)異常或者超時(shí)時(shí),Dubbo會(huì)自動(dòng)調(diào)用Mock中的方法返回預(yù)設(shè)的值。
2、服務(wù)熔斷
服務(wù)熔斷是指當(dāng)系統(tǒng)中某個(gè)服務(wù)出現(xiàn)異常或者超時(shí)等情況時(shí),Dubbo會(huì)在一定時(shí)間內(nèi)暫停對(duì)該服務(wù)的調(diào)用,防止服務(wù)雪崩,提高系統(tǒng)的可用性。Dubbo支持配置熔斷的時(shí)間窗口和請(qǐng)求的最大失敗次數(shù),當(dāng)超過(guò)這個(gè)次數(shù)后,Dubbo將不再調(diào)用該服務(wù),直到時(shí)間窗口結(jié)束。
Dubbo的服務(wù)熔斷是通過(guò)circuit breaker模式來(lái)實(shí)現(xiàn)的,Dubbo會(huì)根據(jù)服務(wù)的負(fù)載情況來(lái)判斷是否需要熔斷。
3、服務(wù)隔離
服務(wù)隔離指的是將不同的服務(wù)放在不同的進(jìn)程或者容器中運(yùn)行,防止某個(gè)服務(wù)出現(xiàn)故障影響到其他服務(wù)的正常運(yùn)行。Dubbo支持將不同的服務(wù)放在不同的進(jìn)程或者容器中運(yùn)行,實(shí)現(xiàn)服務(wù)的隔離。
4、重試機(jī)制
重試機(jī)制指的是在服務(wù)調(diào)用失敗后,Dubbo會(huì)根據(jù)一定的規(guī)則進(jìn)行重試,直到服務(wù)調(diào)用成功或達(dá)到最大重試次數(shù)。Dubbo可以配置重試次數(shù)、重試間隔時(shí)間等參數(shù),實(shí)現(xiàn)重試機(jī)制。
Dubbo默認(rèn)提供了重試機(jī)制,可以通過(guò)在配置文件中設(shè)置retries參數(shù)來(lái)啟用。如果服務(wù)調(diào)用失敗,則Dubbo會(huì)自動(dòng)重新嘗試調(diào)用服務(wù),直到達(dá)到最大重試次數(shù)或服務(wù)調(diào)用成功。重試過(guò)程中,Dubbo會(huì)等待一定的時(shí)間間隔,以避免對(duì)服務(wù)的過(guò)度壓力。
六、Dubbo的負(fù)載均衡策略
1、輪詢(xún)負(fù)載均衡
輪詢(xún)負(fù)載均衡算法是默認(rèn)的算法,它會(huì)將服務(wù)提供者列表按照順序輪流選擇。如果其中一個(gè)服務(wù)提供者的性能較差,那么使用輪詢(xún)算法會(huì)導(dǎo)致它會(huì)被頻繁地請(qǐng)求,從而降低整體性能。因此,輪詢(xún)算法適用于所有服務(wù)提供者性能相同的情況下。
2、隨機(jī)負(fù)載均衡
隨機(jī)負(fù)載均衡算法可以隨機(jī)選擇一個(gè)服務(wù)提供者來(lái)處理請(qǐng)求。與輪詢(xún)算法相比,隨機(jī)算法并不考慮服務(wù)提供者之間的負(fù)載或性能,因此速度更快。但是,在某些情況下,服務(wù)提供者之間的負(fù)載差異太大,隨機(jī)算法可能會(huì)導(dǎo)致某些服務(wù)提供者接受過(guò)多的請(qǐng)求。因此,隨機(jī)算法適用于所有服務(wù)提供者性能相同的情況下,或服務(wù)提供者之間的性能差異較小的情況下。
3、最少活躍調(diào)用負(fù)載均衡
最少活躍調(diào)用(Least Active)是一種智能負(fù)載均衡算法。該算法會(huì)選擇活躍調(diào)用數(shù)最少的服務(wù)提供者來(lái)處理請(qǐng)求,也就是當(dāng)前正忙碌程度最小的服務(wù)提供者。這種算法適合那些提供長(zhǎng)時(shí)間服務(wù)的服務(wù)者,比如像查詢(xún)某種緩存服務(wù),查詢(xún)開(kāi)始不占用太多服務(wù)器資源,但是隨著查詢(xún)次數(shù)增加會(huì)占用 相當(dāng)多的服務(wù)端資源,這時(shí)候使用Least Active算法可以選取負(fù)載最小的服務(wù)提供者,避免資源過(guò)度占用。
4、一致性哈希負(fù)載均衡
一致性哈希負(fù)載均衡是一種智能負(fù)載均衡算法,在分布式場(chǎng)景下,可以保證負(fù)載均衡和數(shù)據(jù)一致性。該算法會(huì)將所有服務(wù)提供者看作一個(gè)環(huán),每個(gè)服務(wù)提供者對(duì)應(yīng)一個(gè)獨(dú)特的哈希值。
對(duì)于一個(gè)請(qǐng)求,一致性哈希算法通過(guò)哈希值將其映射到服務(wù)提供者環(huán)中的一個(gè)位置,然后選擇服務(wù)提供者環(huán)上第一個(gè)順時(shí)針?lè)较蛴龅降姆?wù)提供者來(lái)處理請(qǐng)求。
該算法優(yōu)點(diǎn)在于,當(dāng)新增或刪除一個(gè)服務(wù)提供者時(shí),僅需重新映射部分請(qǐng)求到新的服務(wù)提供者,而不是全部請(qǐng)求,從而避免了大規(guī)模遷移,可以提高系統(tǒng)的穩(wěn)定性和擴(kuò)展性。
七、Dubbo的集群容錯(cuò)機(jī)制
1、失敗自動(dòng)切換
在調(diào)用服務(wù)時(shí),Dubbo會(huì)選擇一個(gè)可用的服務(wù)提供者,如果該提供者未響應(yīng)或發(fā)生異常,Dubbo會(huì)自動(dòng)切換到下一個(gè)可用的服務(wù)提供者進(jìn)行調(diào)用,這就是失敗自動(dòng)切換機(jī)制。
2、失敗安全保護(hù)
在失敗自動(dòng)切換的基礎(chǔ)上,Dubbo提供了另一種集群容錯(cuò)機(jī)制:失敗安全保護(hù)。它的原理是當(dāng)出現(xiàn)某個(gè)服務(wù)提供者不可用時(shí),Dubbo會(huì)暫時(shí)禁用該服務(wù)提供者,一段時(shí)間后再次開(kāi)啟,檢查其可用性。通過(guò)這種方式,Dubbo保證了系統(tǒng)的穩(wěn)定性以及在出現(xiàn)異常情況時(shí)調(diào)用的可用性。
3、并行調(diào)用
Dubbo在集群容錯(cuò)中提供了一種新的機(jī)制:并行調(diào)用。
當(dāng)服務(wù)提供者在某個(gè)時(shí)間段內(nèi)不能響應(yīng)請(qǐng)求時(shí),Dubbo會(huì)開(kāi)啟多個(gè)服務(wù)提供者實(shí)例,將請(qǐng)求發(fā)送給這些實(shí)例進(jìn)行并行處理,快速的獲取結(jié)果并返回給服務(wù)消費(fèi)者。
4、快速失敗
快速失敗機(jī)制指當(dāng)某個(gè)服務(wù)提供者出現(xiàn)異常時(shí),Dubbo會(huì)快速的拋出異常給服務(wù)消費(fèi)者,避免服務(wù)調(diào)用者長(zhǎng)時(shí)間等待請(qǐng)求響應(yīng)結(jié)果。同時(shí),Dubbo也提供了一個(gè)超時(shí)時(shí)間,如果服務(wù)提供者在規(guī)定時(shí)間內(nèi)未能響應(yīng)請(qǐng)求,則Dubbo會(huì)快速的拋出異常給服務(wù)消費(fèi)者,避免請(qǐng)求長(zhǎng)時(shí)間等待沒(méi)有響應(yīng)結(jié)果。
八、Dubbo的底層通信
1、Dubbo的網(wǎng)絡(luò)通信
Dubbo的底層通信是建立在Netty的通信框架上的,Netty是一個(gè)高性能的、異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架。在Dubbo中,Netty扮演著很重要的角色,其提供的通信能力能夠支持Dubbo不同節(jié)點(diǎn)之間的通信,并且通過(guò)高效的I/O操作完成請(qǐng)求響應(yīng)的過(guò)程。Dubbo利用Netty的通信框架實(shí)現(xiàn)了從網(wǎng)絡(luò)層到協(xié)議層的完整封裝,使得Dubbo的通信效率得到很大的提升。
Dubbo的網(wǎng)絡(luò)通信過(guò)程是非常復(fù)雜的,在服務(wù)提供者和服務(wù)消費(fèi)者之間建立連接,并進(jìn)行請(qǐng)求響應(yīng)的過(guò)程中,每一步都可能出現(xiàn)各種問(wèn)題,例如網(wǎng)絡(luò)延遲、服務(wù)端宕機(jī)、序列化錯(cuò)誤等等,因此Dubbo在網(wǎng)絡(luò)通信過(guò)程中加入了多種機(jī)制來(lái)提高網(wǎng)絡(luò)通信的效率和安全性。其中,比較重要的機(jī)制包括心跳機(jī)制、序列化與反序列化、長(zhǎng)連接池等等。
2、序列化和反序列化
Dubbo利用Java自帶的ObjectInputStream和ObjectOutputStream類(lèi)實(shí)現(xiàn)序列化和反序列化的過(guò)程,通過(guò)序列化和反序列化使得復(fù)雜的對(duì)象能夠在網(wǎng)絡(luò)中傳輸。
Dubbo支持多種序列化協(xié)議,包括Java原生的序列化協(xié)議(即Dubbo協(xié)議)、JSON、Hessian、Kryo等。Dubbo默認(rèn)采用Java原生的序列化協(xié)議,雖然其具有很好的兼容性,但是其性能較差。因此,通常情況下建議使用其他的序列化協(xié)議,例如Hessian或Kryo,以提高序列化的效率。
九、Dubbo的擴(kuò)展機(jī)制
1、自定義SPI擴(kuò)展
Dubbo采用SPI(Service Provider Interface)的機(jī)制,用于擴(kuò)展或替換框架中的某個(gè)實(shí)現(xiàn)。Dubbo對(duì)SPI機(jī)制的擴(kuò)展可以通過(guò)Java的SPI機(jī)制實(shí)現(xiàn),也可以通過(guò)Dubbo自己定義的SPI機(jī)制實(shí)現(xiàn),Dubbo自己定義的SPI機(jī)制要完善一些。
Dubbo自定義的SPI機(jī)制定義了一個(gè)擴(kuò)展點(diǎn)接口,每個(gè)擴(kuò)展點(diǎn)接口對(duì)應(yīng)了一組擴(kuò)展實(shí)現(xiàn)類(lèi),而這些實(shí)現(xiàn)類(lèi)都必須要使用SPI的配置文件進(jìn)行配置。
Dubbo的擴(kuò)展點(diǎn)接口中,我們可以定義類(lèi)似于ExtensionLoader這樣的類(lèi),通過(guò)這些類(lèi),我們可以獲取到相關(guān)擴(kuò)展實(shí)現(xiàn)類(lèi),從而進(jìn)行自定義的擴(kuò)展。
2、自定義過(guò)濾器
Dubbo的過(guò)濾器是一種攔截器,可以在請(qǐng)求到達(dá)消費(fèi)者時(shí)、在提供者執(zhí)行服務(wù)邏輯前后以及在調(diào)用方收到響應(yīng)時(shí)對(duì)請(qǐng)求和響應(yīng)進(jìn)行處理。Dubbo提供了一些內(nèi)置的過(guò)濾器,例如安全過(guò)濾器、異常過(guò)濾器、日志過(guò)濾器等。
不過(guò),Dubbo也允許我們自定義過(guò)濾器來(lái)實(shí)現(xiàn)自己的特定需求,自定義的過(guò)濾器需要實(shí)現(xiàn)Filter接口,然后通過(guò)SPI機(jī)制進(jìn)行擴(kuò)展。
自定義的過(guò)濾器可以用于多種場(chǎng)景,例如監(jiān)控、鑒權(quán)、統(tǒng)計(jì)和日志等。
3、自定義負(fù)載均衡策略
Dubbo框架內(nèi)置了多種負(fù)載均衡策略,例如隨機(jī)負(fù)載均衡、輪詢(xún)負(fù)載均衡和最少活躍調(diào)用負(fù)載均衡等。但是,這些負(fù)載均衡策略并不一定適用于所有的場(chǎng)景,因此Dubbo也允許我們自定義負(fù)載均衡策略。
自定義負(fù)載均衡策略需要實(shí)現(xiàn)LoadBalance接口,然后通過(guò)SPI機(jī)制進(jìn)行擴(kuò)展。自定義負(fù)載均衡策略可以根據(jù)不同場(chǎng)景的需求,實(shí)現(xiàn)不同的算法和邏輯,從而更好地滿足業(yè)務(wù)需求。
十、總結(jié)
1、Dubbo的優(yōu)缺點(diǎn)
Dubbo是阿里巴巴公司開(kāi)發(fā)的一款高性能、高可用的分布式服務(wù)框架。在分布式架構(gòu)中,Dubbo擔(dān)任著重要的角色,實(shí)現(xiàn)了服務(wù)的注冊(cè)、發(fā)現(xiàn)、負(fù)載均衡、容錯(cuò)等功能,為分布式系統(tǒng)提供了更好的可擴(kuò)展性和可維護(hù)性。
同時(shí),Dubbo也存在一些優(yōu)缺點(diǎn)。
首先,Dubbo具有較強(qiáng)的可定制化性,可以根據(jù)實(shí)際業(yè)務(wù)需求來(lái)選擇不同的配置和擴(kuò)展機(jī)制。
其次,Dubbo的性能表現(xiàn)出色,適用于高并發(fā)、大規(guī)模的分布式系統(tǒng)。但是,Dubbo也存在一些問(wèn)題,比如復(fù)雜的部署和配置流程,限制了其在小型項(xiàng)目中的應(yīng)用。
2、Dubbo的未來(lái)發(fā)展趨勢(shì)
未來(lái),Dubbo將會(huì)繼續(xù)發(fā)展和改進(jìn),市場(chǎng)對(duì)Dubbo的需求也將繼續(xù)增加。除了更新迭代,Dubbo還將更加注重安全、大數(shù)據(jù)等領(lǐng)域的拓展和應(yīng)用。
總的來(lái)說(shuō),Dubbo在分布式架構(gòu)中的地位和應(yīng)用前景都非常廣闊。
本文轉(zhuǎn)載自微信公眾號(hào)「哪吒編程」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系哪吒編程公眾號(hào)。