日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

今天詳細(xì)的分解一下Dubbo的擴(kuò)展機(jī)制,實(shí)現(xiàn)快速入門,豐富個(gè)人簡歷,提高面試level,給自己增加一點(diǎn)談資,秒變面試小達(dá)人,BAT不是夢。

說真的,從零學(xué)習(xí)Dubbo,看這個(gè)系列足夠了,共10篇,歡迎持續(xù)關(guān)注,相約每天早八點(diǎn)

三分鐘你將學(xué)會(huì):

  1. Dubbo的自適應(yīng)擴(kuò)展機(jī)制
  2. Dubbo的SPI擴(kuò)展機(jī)制
  3. Dubbo的自定義擴(kuò)展點(diǎn)機(jī)制
  4. Dubbo的過濾器擴(kuò)展機(jī)制
  5. Dubbo的負(fù)載均衡擴(kuò)展機(jī)制;
  6. Dubbo的容錯(cuò)機(jī)制擴(kuò)展;

一、Dubbo擴(kuò)展機(jī)制的概述

Dubbo是一個(gè)高性能的分布式服務(wù)框架,廣泛應(yīng)用于各種規(guī)模和種類的企業(yè)級項(xiàng)目中。在實(shí)際應(yīng)用過程中,Dubbo的核心能力是擴(kuò)展機(jī)制,它可以讓Dubbo具有更強(qiáng)的可定制化能力,也可以讓Dubbo更好地適應(yīng)各種應(yīng)用場景。

圖片

Dubbo的擴(kuò)展機(jī)制

Dubbo的擴(kuò)展機(jī)制主要包括:自適應(yīng)擴(kuò)展機(jī)制、SPI擴(kuò)展機(jī)制、自定義擴(kuò)展點(diǎn)機(jī)制、過濾器擴(kuò)展機(jī)制、負(fù)載均衡擴(kuò)展機(jī)制和容錯(cuò)機(jī)制擴(kuò)展

這些機(jī)制使得Dubbo的使用更加靈活方便,可以滿足不同需要的業(yè)務(wù)場景,也可以根據(jù)實(shí)際情況來選擇合適的擴(kuò)展機(jī)制。

在Dubbo的擴(kuò)展機(jī)制中,尤其需要注意自定義擴(kuò)展點(diǎn)機(jī)制和SPI擴(kuò)展機(jī)制。這些機(jī)制是Dubbo中較為重要和常用的擴(kuò)展機(jī)制,充分了解這些機(jī)制可以讓應(yīng)用程序更加靈活和可定制。

下圖展示了Dubbo擴(kuò)展機(jī)制的調(diào)用流程:

圖片

Dubbo擴(kuò)展機(jī)制

上圖中,Dubbo客戶端首先會(huì)通過ExtensionLoader加載需要使用的擴(kuò)展點(diǎn),ExtensionLoader會(huì)根據(jù)客戶端傳入的擴(kuò)展點(diǎn)名和配置,創(chuàng)建對應(yīng)的擴(kuò)展點(diǎn)實(shí)例,并返回給客戶端,客戶端再通過返回的擴(kuò)展點(diǎn)實(shí)例調(diào)用相應(yīng)的方法。

二、Dubbo的自適應(yīng)擴(kuò)展機(jī)制

1、什么是自適應(yīng)擴(kuò)展機(jī)制

自適應(yīng)擴(kuò)展機(jī)制是Dubbo提供的一種機(jī)制,它可以使Dubbo框架根據(jù)實(shí)際使用情況動(dòng)態(tài)地選擇不同的擴(kuò)展實(shí)現(xiàn),從而達(dá)到最優(yōu)的效果。

?自適應(yīng)擴(kuò)展機(jī)制的實(shí)現(xiàn)方式是通過在擴(kuò)展接口的代理類中,根據(jù)實(shí)際情況動(dòng)態(tài)地生成對應(yīng)擴(kuò)展實(shí)現(xiàn)的代理類實(shí)例。

下圖是自適應(yīng)擴(kuò)展機(jī)制的詳細(xì)時(shí)序圖:

圖片

自適應(yīng)擴(kuò)展機(jī)制

上圖中:

  1. Client先調(diào)用ExtensionLoader加載擴(kuò)展點(diǎn),并解析配置文件;
  2. ExtensionLoader根據(jù)配置文件查找實(shí)現(xiàn)類
  3. 然后創(chuàng)建一個(gè)AdaptiveExtension的代理對象,并將該代理對象返回給Client;
  4. Client調(diào)用代理對象的方法時(shí),AdaptiveExtension會(huì)根據(jù)配置使用具體的擴(kuò)展點(diǎn)實(shí)現(xiàn),并將調(diào)用轉(zhuǎn)發(fā)給具體的擴(kuò)展點(diǎn)實(shí)現(xiàn);
  5. 最后將結(jié)果返回給Client;

2、自適應(yīng)擴(kuò)展機(jī)制的使用示例

在Dubbo框架中,有一個(gè)名為Protocol的擴(kuò)展接口,它有多種不同的實(shí)現(xiàn)方式,如dubbo、rmi、http等。在使用Dubbo時(shí),我們可以通過@Reference注解來注入對應(yīng)的擴(kuò)展實(shí)現(xiàn),如:

@Reference(protocol = "dubbo")
private DemoService demoService;
 

在上述代碼中,我們指定了使用dubbo協(xié)議的DemoService接口的擴(kuò)展實(shí)現(xiàn)。

我們也可以通過adaptive屬性來實(shí)現(xiàn)自適應(yīng)調(diào)用,如:

@Reference(adaptive = "true")
private Protocol protocol;

 

在上述代碼中,我們使用了adaptive屬性,并注入了Protocol類型的實(shí)例。這時(shí),Dubbo框架會(huì)根據(jù)實(shí)際情況動(dòng)態(tài)地生成對應(yīng)實(shí)現(xiàn)的代理類,并返回對應(yīng)的實(shí)例。

三、Dubbo的SPI擴(kuò)展機(jī)制

1、什么是SPI擴(kuò)展機(jī)制

Dubbo使用了JAVA的SPI(Service Provider Interface)擴(kuò)展機(jī)制。SPI是JDK內(nèi)置的一種服務(wù)發(fā)現(xiàn)機(jī)制,其具體實(shí)現(xiàn)方式是在資源文件META-INF/services中通過名稱為SPI接口的全限定類名創(chuàng)建一個(gè)文本文件,在這個(gè)文本文件中可以寫入該SPI接口的實(shí)現(xiàn)類全限定類名,這樣可以實(shí)現(xiàn)動(dòng)態(tài)加載實(shí)現(xiàn)類的目的。

?Dubbo中的SPI擴(kuò)展機(jī)制能夠在不修改核心源代碼的前提下,通過修改配置文件或者實(shí)現(xiàn)自定義拓展類的方式來替換或增加核心功能。

下圖描述了 Dubbo SPI 擴(kuò)展機(jī)制的工作流程:

圖片

SPI 擴(kuò)展機(jī)制

上圖描述了 Dubbo SPI 擴(kuò)展機(jī)制的工作流程,其中:

  1. 用戶向 Dubbo Framework 請求獲取 ExtensionLoader,ExtensionLoader 是 Dubbo SPI 擴(kuò)展機(jī)制的核心類;
  2. Dubbo Framework 加載 ExtensionLoader,并返回給用戶;
  3. 用戶調(diào)用 ExtensionLoader 的方法;
  4. ExtensionLoader 根據(jù)指定的 Extension 接口,通過 SPI 機(jī)制加載 Extension 實(shí)現(xiàn);
  5. Extension 實(shí)現(xiàn)將被加載,ExtensionLoader 返回 Extension 實(shí)現(xiàn)給用戶;

2、SPI擴(kuò)展機(jī)制的使用示例

首先,我們需要定義一個(gè)SPI擴(kuò)展接口,讓Dubbo的擴(kuò)展實(shí)現(xiàn)類都實(shí)現(xiàn)該接口。

示例代碼:

package com.example.extension;

import com.alibaba.dubbo.common.extension.SPI;

@SPI("default")
public interface PrintService {
    void print(String msg);
}

 

在接口上添加@SPI注解,指定該擴(kuò)展的默認(rèn)實(shí)現(xiàn)類。

然后,我們需要在META-INF/services目錄下創(chuàng)建一個(gè)“接口全限定類名”的文件名的文件,文件中寫入我們實(shí)現(xiàn)的SPI擴(kuò)展類的全限定類名。

比如我們需要同過實(shí)現(xiàn)PrintService接口來實(shí)現(xiàn)打印功能,那么我們在META-INF/services/目錄下創(chuàng)建一個(gè)名為“com.example.extension.PrintService”的文件,文件內(nèi)容為:

 

com.example.extension.impl.ConsolePrintServiceImpl

 

接下來,我們就可以通過Dubbo框架自動(dòng)加載通過SPI機(jī)制注冊的實(shí)現(xiàn)類了。

示例代碼:

AnnotationConfigApplicationContext context = 
new AnnotationConfigApplicationContext(Main.class);
    PrintService printService = 
    ExtensionLoader.getExtensionLoader(PrintService.class).getDefaultExtension();
    printService.print("hello world!");

 

以上代碼中,我們使用Dubbo的擴(kuò)展加載器ExtensionLoader來獲取PrintService接口的默認(rèn)實(shí)現(xiàn)類,然后調(diào)用該實(shí)現(xiàn)類的print()方法即可實(shí)現(xiàn)打印功能。

3、Dubbo的SPI擴(kuò)展機(jī)制中自定義擴(kuò)展點(diǎn)的實(shí)現(xiàn)示例

在Dubbo框架中,我們可以通過自定義擴(kuò)展點(diǎn)來增強(qiáng)Dubbo的功能。

自定義擴(kuò)展點(diǎn)需要實(shí)現(xiàn)Dubbo提供的ExtensionFactory接口,并在META-INF/dubbo/internal/?路徑下創(chuàng)建一個(gè)文件名為com.alibaba.dubbo.common.extension.ExtensionFactory的文件,文件中寫入擴(kuò)展點(diǎn)實(shí)現(xiàn)類的全限定類名。

示例代碼:

 

package com.example.extension;

import com.alibaba.dubbo.common.extension.ExtensionFactory;

public class MyExtensionFactory implements ExtensionFactory {
    @Override
    public <T> T getExtension(Class<T> type, String name) {
        if (type.equals(PrintService.class)) {
            return (T) new ConsolePrintServiceImpl();
        }
        return null;
    }
}

 

在MyExtensionFactory中實(shí)現(xiàn)getExtension()方法,并根據(jù)type參數(shù)判斷獲取哪個(gè)擴(kuò)展實(shí)現(xiàn)類。

在本示例中,我們僅僅實(shí)現(xiàn)了PrintService接口的實(shí)現(xiàn)類,因此只需要判斷type參數(shù)是否為PrintService類即可。

下一步,我們需要在META-INF/dubbo/internal/目錄下創(chuàng)建一個(gè)名為com.alibaba.dubbo.common.extension.ExtensionFactory的文件,文件內(nèi)容為我們實(shí)現(xiàn)的擴(kuò)展點(diǎn)實(shí)現(xiàn)類全限定類名。

比如我們實(shí)現(xiàn)的擴(kuò)展點(diǎn)實(shí)現(xiàn)類為com.example.extension.MyExtensionFactory?,那么我們就要在META-INF/dubbo/internal/目錄下創(chuàng)建一個(gè)名為com.alibaba.dubbo.common.extension.ExtensionFactory?的文件,并將文件內(nèi)容寫為com.example.extension.MyExtensionFactory。

最后,我們在程序中就可以使用自定義的擴(kuò)展點(diǎn)了。示例代碼:

AnnotationConfigApplicationContext context = 
new AnnotationConfigApplicationContext(Main.class);
PrintService printService = 
ExtensionLoader.getExtensionLoader(PrintService.class).getExtension("console");
printService.print("hello world!");
 

在以上示例代碼中,我們通過getExtension()方法來獲取PrintService接口的實(shí)現(xiàn)類。getExtension()方法中的參數(shù)為擴(kuò)展點(diǎn)的name屬性,該屬性值默認(rèn)為“default”。

在本示例中我們將name的值設(shè)置為“console”,因此即使用了我們自定義的擴(kuò)展點(diǎn)實(shí)現(xiàn)類。

四、Dubbo的自定義擴(kuò)展點(diǎn)機(jī)制

1、什么是自定義擴(kuò)展點(diǎn)機(jī)制

Dubbo的自定義擴(kuò)展點(diǎn)機(jī)制是在SPI擴(kuò)展機(jī)制的基礎(chǔ)上,增加了自定義擴(kuò)展點(diǎn)的實(shí)現(xiàn)方式。通過Dubbo的擴(kuò)展機(jī)制,我們可以通過配置文件切換Dubbo內(nèi)部的實(shí)現(xiàn)方式,但是對于用戶自己實(shí)現(xiàn)的功能模塊,如何進(jìn)行擴(kuò)展呢?

這里就需要用到自定義擴(kuò)展點(diǎn)機(jī)制了。

下圖是自定義擴(kuò)展點(diǎn)機(jī)制的詳細(xì)時(shí)序圖:

圖片

自定義擴(kuò)展點(diǎn)機(jī)制

在上圖中:

  1. 用戶首先將自己實(shí)現(xiàn)的擴(kuò)展點(diǎn)注冊到Dubbo中;
  2. 然后在需要使用該擴(kuò)展點(diǎn)的時(shí)候,Dubbo會(huì)根據(jù)擴(kuò)展點(diǎn)的名稱進(jìn)行查找并返回相應(yīng)的擴(kuò)展點(diǎn)實(shí)例;
  3. 通過這樣的機(jī)制,用戶可以靈活地?cái)U(kuò)展Dubbo的功能,同時(shí)也可以讓Dubbo更加適應(yīng)不同的業(yè)務(wù)場景。

自定義擴(kuò)展點(diǎn)的核心思想就是:“面向接口編程,實(shí)現(xiàn)類實(shí)現(xiàn)接口,接口與實(shí)現(xiàn)類通過擴(kuò)展點(diǎn)Binder關(guān)聯(lián)。”

其中,Binder的定義可以參考以下的代碼:

public interface ExtensionFactory {
    // 返回一個(gè)擴(kuò)展點(diǎn)的代理對象
    <T> T getExtension(Class<T> type, String name) throws IllegalStateException;
}

public interface ExtensionLoader<T> {
    T getExtension(String name);
}

public interface ExtensionBinder<T> {
    // 綁定
    void bind(T instance);
    // 獲取綁定的擴(kuò)展對象
    T get();
}

public interface ExtensionLoaderListener {
    void onLoad();
}

2、自定義擴(kuò)展點(diǎn)機(jī)制的使用示例

為了更好地理解Dubbo的自定義擴(kuò)展點(diǎn)機(jī)制,我們可以通過一個(gè)簡單的示例來演示其使用方法。假設(shè)我們有一個(gè)接口HelloService,我們想要通過自定義擴(kuò)展點(diǎn)機(jī)制,為這個(gè)接口添加一個(gè)實(shí)現(xiàn)類。

首先,我們需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn)類HelloServiceImpl,該實(shí)現(xiàn)類需要實(shí)現(xiàn)HelloService接口。

接著,我們需要在resources/META-INF/dubbo目錄下創(chuàng)建一個(gè)名為com.xxx.HelloService的文件,該文件中需要指定HelloService接口的實(shí)現(xiàn)類名稱。

helloService=com.xxx.HelloServiceImpl

 

接下來,我們需要在代碼中獲取HelloService接口的實(shí)例。這可以通過以下方式實(shí)現(xiàn):

ExtensionLoader<HelloService> loader = 
ExtensionLoader.getExtensionLoader(HelloService.class);
HelloService helloService = 
loader.getExtension("helloService");
helloService.sayHello();

 

其中,getExtensionLoader()方法用于獲取擴(kuò)展點(diǎn)的ExtensionLoader實(shí)例,getExtension()方法用于 獲取具體的擴(kuò)展實(shí)例。

在上面的代碼中,我們通過“helloService”這個(gè)名稱獲取到了實(shí)現(xiàn)了HelloService接口的HelloServiceImpl實(shí)例,并調(diào)用了其中的sayHello()方法。

通過上述示例,我們可以看出,使用Dubbo的自定義擴(kuò)展點(diǎn)機(jī)制非常簡單,只需要在配置文件中指定實(shí)現(xiàn)類的名稱,然后通過getExtensionLoader()和getExtension()方法獲取實(shí)例即可。

3、Dubbo的自定義擴(kuò)展點(diǎn)機(jī)制的實(shí)現(xiàn)示例

在Dubbo的自定義擴(kuò)展點(diǎn)機(jī)制中,最核心的是ExtensionLoader類和ExtensionFactory類

其中,ExtensionLoader用于加載和管理擴(kuò)展實(shí)例,ExtensionFactory用于創(chuàng)建擴(kuò)展實(shí)例

下面,我們將通過一個(gè)簡單的示例,演示Dubbo的自定義擴(kuò)展點(diǎn)機(jī)制的具體實(shí)現(xiàn)方式。

首先,我們需要定義一個(gè)擴(kuò)展點(diǎn)接口:

public interface HelloService {
    String sayHello(String name);
}

 

接著,我們需要實(shí)現(xiàn)該接口的一個(gè)實(shí)現(xiàn)類:

@SPI("helloWorld")
public class HelloWorldService implements HelloService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name;
    }
}
 

在這里,我們使用了@SPI注解來指定該擴(kuò)展點(diǎn)的默認(rèn)實(shí)現(xiàn),如果配置文件中沒有指定其他實(shí)現(xiàn),則會(huì)使用該默認(rèn)實(shí)現(xiàn)

接下來,我們需要?jiǎng)?chuàng)建一個(gè)名為com.xxx.HelloService的文件,該文件中需要指定擴(kuò)展點(diǎn)接口的實(shí)現(xiàn)類名稱:

helloWorld=com.xxx.HelloWorldService

 

最后,我們需要在代碼中獲取HelloService接口的實(shí)例,這可以通過以下代碼實(shí)現(xiàn):

ExtensionLoader<HelloService> loader = 
ExtensionLoader.getExtensionLoader(HelloService.class);
HelloService helloService = 
loader.getExtension("helloWorld");
System.out.println(helloService.sayHello("Dubbo"));

 

在上述代碼中,我們通過getExtensionLoader()方法獲取HelloService接口的ExtensionLoader實(shí)例,然后通過getExtension()方法獲取名為“helloWorld”的實(shí)現(xiàn)類實(shí)例,并調(diào)用其中的sayHello()方法。

五、Dubbo的過濾器擴(kuò)展機(jī)制

1、Dubbo的過濾器機(jī)制概述

圖片

Dubbo的過濾器機(jī)制允許在調(diào)用前、調(diào)用后以及拋出異常時(shí)執(zhí)行一些額外的操作。過濾器在調(diào)用鏈路中按順序執(zhí)行,可以在過濾器中實(shí)現(xiàn)各種功能,例如:日志記錄、性能統(tǒng)計(jì)、權(quán)限控制等。

圖片

內(nèi)置過濾器

Dubbo中內(nèi)置了多個(gè)過濾器,包括:ClassLoader過濾器、Context過濾器、Generic過濾器、Echo過濾器、Token過濾器、AccessLog過濾器等

下面是Dubbo的過濾器機(jī)制的時(shí)序圖:

圖片

上圖中:

  1. 服務(wù)消費(fèi)者向服務(wù)提供者發(fā)送請求時(shí),請求先經(jīng)過過濾器1;
  2. 如果過濾器1通過則進(jìn)一步經(jīng)過過濾器2;
  3. 如果過濾器2通過則進(jìn)一步經(jīng)過過濾器3;
  4. 如果過濾器3通過則將請求發(fā)送給服務(wù)提供者,服務(wù)提供者處理請求后將響應(yīng)返回給服務(wù)消費(fèi)者,響應(yīng)也會(huì)經(jīng)過相同的過濾器鏈路;
  5. 如果任意一個(gè)過濾器拒絕請求,則直接返回錯(cuò)誤響應(yīng)。

2、過濾器擴(kuò)展機(jī)制的使用示例

Dubbo提供了擴(kuò)展機(jī)制,可以在dubbo配置文件中配置過濾器,示例如下:

<dubbo:provider filter="accessLogFilter" />

在上面的例子中,accessLogFilter表示需要使用的過濾器名稱,可以在dubbo配置文件中通過dubbo:filter標(biāo)簽進(jìn)行定義。

3、自定義過濾器的實(shí)現(xiàn)示例

要實(shí)現(xiàn)自定義過濾器,需要按照以下步驟進(jìn)行:

  1. 定義一個(gè)類實(shí)現(xiàn)org.Apache.dubbo.rpc.Filter接口;
  2. 實(shí)現(xiàn)接口中的方法;
  3. 在META-INF/dubbo目錄下創(chuàng)建一個(gè)以org.apache.dubbo.rpc.Filter接口全限定名為名稱的文件,并在文件中添加自定義過濾器的類名。

下面是一個(gè)自定義的過濾器示例:

package com.example;

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

@Activate(group = "provider")
public class MyFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        // 在這里實(shí)現(xiàn)自己的邏輯
        return invoker.invoke(invocation);
    }
}

在上面的例子中,我們實(shí)現(xiàn)了一個(gè)MyFilter過濾器,并使用@Activate注解指定了它是一個(gè)provider端的過濾器,然后在invoke()方法中編寫自己的邏輯,最后調(diào)用invoker.invoke(invocation)方法來執(zhí)行調(diào)用鏈路中的下一個(gè)過濾器或服務(wù)。

六、Dubbo的負(fù)載均衡擴(kuò)展機(jī)制

1、Dubbo的負(fù)載均衡擴(kuò)展機(jī)制概述

負(fù)載均衡是分布式系統(tǒng)中的一個(gè)重要問題,它可以實(shí)現(xiàn)將請求分?jǐn)偟蕉鄠€(gè)服務(wù)提供者上,提高系統(tǒng)的并發(fā)能力和可用性。

Dubbo的負(fù)載均衡擴(kuò)展機(jī)制允許用戶自定義負(fù)載均衡策略,實(shí)現(xiàn)更加靈活、適合特定場景的負(fù)載均衡算法。

Dubbo內(nèi)置了多種負(fù)載均衡算法,包括隨機(jī)、輪詢、最少活躍調(diào)用等。

下面是Dubbo的負(fù)載均衡擴(kuò)展機(jī)制的時(shí)序圖:

圖片

負(fù)載均衡擴(kuò)展機(jī)制

2、負(fù)載均衡擴(kuò)展機(jī)制的使用示例

Dubbo的負(fù)載均衡擴(kuò)展機(jī)制可以通過在服務(wù)提供方和服務(wù)消費(fèi)方的配置文件中指定負(fù)載均衡策略來使用。

例如,在服務(wù)提供方的配置文件中可以添加以下配置:

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

在服務(wù)消費(fèi)方的配置文件中可以添加以下配置:

<dubbo:reference interface="com.xxx.XxxService" loadbalance="random" />

 

這樣就可以實(shí)現(xiàn)使用Dubbo內(nèi)置的輪詢

3、自定義負(fù)載均衡策略的實(shí)現(xiàn)示例

用戶可以通過實(shí)現(xiàn)Dubbo的LoadBalance接口來自定義負(fù)載均衡策略。

以下是一個(gè)示例:

public class MyLoadBalance implements LoadBalance {
    @Override
    public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
        // 自定義負(fù)載均衡算法實(shí)現(xiàn)
        return invokers.get(0);
    }
}

 

七、Dubbo的容錯(cuò)機(jī)制擴(kuò)展

1、Dubbo的容錯(cuò)機(jī)制概述

Dubbo的容錯(cuò)機(jī)制是指當(dāng)Dubbo服務(wù)調(diào)用出現(xiàn)異常時(shí),Dubbo框架會(huì)根據(jù)預(yù)設(shè)的容錯(cuò)機(jī)制進(jìn)行處理,以保證服務(wù)的高可用性。

Dubbo框架默認(rèn)提供了多種容錯(cuò)機(jī)制,如Failover、Failfast、Failsafe、Failback、Forking等,也支持自定義容錯(cuò)機(jī)制。

Dubbo的容錯(cuò)機(jī)制通常是通過在客戶端代理層實(shí)現(xiàn)的,當(dāng)遠(yuǎn)程服務(wù)調(diào)用出現(xiàn)異常時(shí),客戶端代理會(huì)根據(jù)預(yù)設(shè)的容錯(cuò)機(jī)制進(jìn)行重試或處理,以保證服務(wù)的高可用性。

圖片

容錯(cuò)機(jī)制

在Dubbo的容錯(cuò)機(jī)制中,ClusterInvoker負(fù)責(zé)調(diào)用遠(yuǎn)程服務(wù),并進(jìn)行容錯(cuò)處理。當(dāng)調(diào)用遠(yuǎn)程服務(wù)發(fā)生異常時(shí),Dubbo會(huì)按照以下順序進(jìn)行容錯(cuò)處理:

  1. ClusterInvoker處理異常;
  2. 如果ClusterInvoker處理異常失敗,則交由Router處理異常;
  3. 如果Router處理異常失敗,則交由LoadBalance處理異常;
  4. 如果LoadBalance處理異常失敗,則拋出異常給InvokerInvocationHandler,最終拋出給Consumer。同時(shí),Dubbo還會(huì)將異常信息進(jìn)行監(jiān)控,并更新調(diào)用統(tǒng)計(jì)信息。

2、容錯(cuò)機(jī)制擴(kuò)展的使用示例

Dubbo默認(rèn)的容錯(cuò)機(jī)制是Failover,即自動(dòng)切換重試其他節(jié)點(diǎn),達(dá)到容錯(cuò)和負(fù)載均衡的效果。如果需要使用其他容錯(cuò)機(jī)制,可以通過在服務(wù)提供方和服務(wù)消費(fèi)方的配置文件中進(jìn)行配置。

例如,我們可以通過以下方式配置使用Failfast容錯(cuò)機(jī)制:

在服務(wù)提供方的配置文件中增加如下配置:

<dubbo:service interface="com.example.service.SomeService" retries="0"/>

在服務(wù)消費(fèi)方的配置文件中增加如下配置:

<dubbo:reference interface="com.example.service.SomeService" check="false" cluster="failfast"/>

 

這樣,在服務(wù)調(diào)用出現(xiàn)異常時(shí),Dubbo框架會(huì)自動(dòng)使用Failfast容錯(cuò)機(jī)制進(jìn)行處理,即只進(jìn)行一次調(diào)用,若調(diào)用失敗則立即拋出異常,不進(jìn)行重試。

3、自定義容錯(cuò)策略的實(shí)現(xiàn)示例

如果需要實(shí)現(xiàn)自定義的容錯(cuò)策略,可以通過繼承org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker?類,并實(shí)現(xiàn)org.apache.dubbo.rpc.Invoker接口,來自定義容錯(cuò)策略的實(shí)現(xiàn)。

例如,我們可以通過以下代碼實(shí)現(xiàn)一個(gè)自定義的容錯(cuò)策略:

public class MyClusterInvoker<T> extends AbstractClusterInvoker<T> {
    public MyClusterInvoker(Directory<T> directory) {
        super(directory);
    }

    @Override
    protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
        // 自定義容錯(cuò)邏輯
        ...
    }
}
 

在實(shí)現(xiàn)自定義容錯(cuò)策略后,需要在服務(wù)提供方和服務(wù)消費(fèi)方的配置文件中進(jìn)行配置。

例如,在服務(wù)提供方的配置文件中增加如下配置:

 

<dubbo:service interface="com.example.service.SomeService" cluster="myClusterInvoker"/>

 

在服務(wù)消費(fèi)方的配置文件中增加如下配置:

<dubbo:reference interface="com.example.service.SomeService" check="false" cluster="myClusterInvoker"/>

 

這樣,在服務(wù)調(diào)用時(shí),Dubbo框架會(huì)使用我們自定義的MyClusterInvoker容錯(cuò)策略進(jìn)行處理。

八、Dubbo的擴(kuò)展機(jī)制實(shí)踐

1、實(shí)現(xiàn)一個(gè)使用自定義擴(kuò)展點(diǎn)、過濾器、負(fù)載均衡器和容錯(cuò)機(jī)制的 Dubbo 服務(wù)

在這個(gè)實(shí)踐中,我們將實(shí)現(xiàn)一個(gè)使用自定義擴(kuò)展點(diǎn)、過濾器、負(fù)載均衡器和容錯(cuò)機(jī)制的 Dubbo 服務(wù)。

2、首先,我們需要定義一個(gè)服務(wù)接口。

例如,我們可以定義一個(gè)名為 SomeService 的服務(wù)接口,如下所示:

public interface SomeService {
    String sayHello(String name);
}

 

3、然后,我們需要實(shí)現(xiàn)該服務(wù)接口。

例如,我們可以實(shí)現(xiàn)一個(gè)名為 SomeServiceImpl 的服務(wù)實(shí)現(xiàn)類,如下所示:

public class SomeServiceImpl implements SomeService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}
 

4、接下來,我們需要配置 Dubbo 的擴(kuò)展點(diǎn)、過濾器、負(fù)載均衡器和容錯(cuò)機(jī)制。

例如,我們可以在服務(wù)提供方和服務(wù)消費(fèi)方的配置文件中進(jìn)行如下配置:

<!-- 擴(kuò)展點(diǎn)配置 -->
<dubbo:protocol name="dubbo" extensinotallow="com.example.extension.MyProtocol"/>

<!-- 過濾器配置 -->
<dubbo:provider filter="com.example.filter.MyProviderFilter"/>
<dubbo:consumer filter="com.example.filter.MyConsumerFilter"/>

<!-- 負(fù)載均衡器配置 -->
<dubbo:reference interface="com.example.service.SomeService" loadbalance="com.example.loadbalance.MyLoadBalance"/>

<!-- 容錯(cuò)機(jī)制配置 -->
<dubbo:service interface="com.example.service.SomeService" cluster="com.example.cluster.MyCluster"/>
<dubbo:reference interface="com.example.service.SomeService" cluster="com.example.cluster.MyCluster"/>

其中,com.example.extension.MyProtocol? 是一個(gè)自定義的 Dubbo 協(xié)議擴(kuò)展點(diǎn)實(shí)現(xiàn)類,com.example.filter.MyProviderFilter? 和 com.example.filter.MyConsumerFilter? 是自定義的 Dubbo 過濾器實(shí)現(xiàn)類,com.example.loadbalance.MyLoadBalance? 是一個(gè)自定義的 Dubbo 負(fù)載均衡器實(shí)現(xiàn)類,com.example.cluster.MyCluster 是一個(gè)自定義的 Dubbo 容錯(cuò)機(jī)制實(shí)現(xiàn)類。

5、最后,我們可以使用 Dubbo 的 API 在客戶端調(diào)用該服務(wù)。

例如,我們可以使用如下代碼在客戶端調(diào)用該服務(wù):

 

// 獲取 Dubbo 服務(wù)引用
SomeService someService = DubboReferenceBuilder.newBuilder()
        .setInterface(SomeService.class)
        .setUrl("dubbo://localhost:20880")
        .build();

// 調(diào)用 Dubbo 服務(wù)
String result = someService.sayHello("Dubbo");
System.out.println(result);
  •  

這樣,我們就實(shí)現(xiàn)了一個(gè)使用自定義擴(kuò)展點(diǎn)、過濾器、負(fù)載均衡器和容錯(cuò)機(jī)制的 Dubbo 服務(wù)

本文轉(zhuǎn)載自微信公眾號「哪吒編程」

分享到:
標(biāo)簽:Dubbo
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定