圖解Dubbo,六種擴展機制詳解
大家好,我是哪吒。
今天詳細(xì)的分解一下Dubbo的擴展機制,實現(xiàn)快速入門,豐富個人簡歷,提高面試level,給自己增加一點談資,秒變面試小達(dá)人,BAT不是夢。
說真的,從零學(xué)習(xí)Dubbo,看這個系列足夠了,共10篇,歡迎持續(xù)關(guān)注,相約每天早八點。
三分鐘你將學(xué)會:
- Dubbo的自適應(yīng)擴展機制
- Dubbo的SPI擴展機制
- Dubbo的自定義擴展點機制
- Dubbo的過濾器擴展機制
- Dubbo的負(fù)載均衡擴展機制;
- Dubbo的容錯機制擴展;
一、Dubbo擴展機制的概述
Dubbo是一個高性能的分布式服務(wù)框架,廣泛應(yīng)用于各種規(guī)模和種類的企業(yè)級項目中。在實際應(yīng)用過程中,Dubbo的核心能力是擴展機制,它可以讓Dubbo具有更強的可定制化能力,也可以讓Dubbo更好地適應(yīng)各種應(yīng)用場景。
Dubbo的擴展機制
Dubbo的擴展機制主要包括:自適應(yīng)擴展機制、SPI擴展機制、自定義擴展點機制、過濾器擴展機制、負(fù)載均衡擴展機制和容錯機制擴展。
這些機制使得Dubbo的使用更加靈活方便,可以滿足不同需要的業(yè)務(wù)場景,也可以根據(jù)實際情況來選擇合適的擴展機制。
在Dubbo的擴展機制中,尤其需要注意自定義擴展點機制和SPI擴展機制。這些機制是Dubbo中較為重要和常用的擴展機制,充分了解這些機制可以讓應(yīng)用程序更加靈活和可定制。
下圖展示了Dubbo擴展機制的調(diào)用流程:
Dubbo擴展機制
上圖中,Dubbo客戶端首先會通過ExtensionLoader加載需要使用的擴展點,ExtensionLoader會根據(jù)客戶端傳入的擴展點名和配置,創(chuàng)建對應(yīng)的擴展點實例,并返回給客戶端,客戶端再通過返回的擴展點實例調(diào)用相應(yīng)的方法。
二、Dubbo的自適應(yīng)擴展機制
1、什么是自適應(yīng)擴展機制
自適應(yīng)擴展機制是Dubbo提供的一種機制,它可以使Dubbo框架根據(jù)實際使用情況動態(tài)地選擇不同的擴展實現(xiàn),從而達(dá)到最優(yōu)的效果。
?自適應(yīng)擴展機制的實現(xiàn)方式是通過在擴展接口的代理類中,根據(jù)實際情況動態(tài)地生成對應(yīng)擴展實現(xiàn)的代理類實例。
下圖是自適應(yīng)擴展機制的詳細(xì)時序圖:
自適應(yīng)擴展機制
上圖中:
- Client先調(diào)用ExtensionLoader加載擴展點,并解析配置文件;
- ExtensionLoader根據(jù)配置文件查找實現(xiàn)類
- 然后創(chuàng)建一個AdaptiveExtension的代理對象,并將該代理對象返回給Client;
- Client調(diào)用代理對象的方法時,AdaptiveExtension會根據(jù)配置使用具體的擴展點實現(xiàn),并將調(diào)用轉(zhuǎn)發(fā)給具體的擴展點實現(xiàn);
- 最后將結(jié)果返回給Client;
2、自適應(yīng)擴展機制的使用示例
在Dubbo框架中,有一個名為Protocol的擴展接口,它有多種不同的實現(xiàn)方式,如dubbo、rmi、http等。在使用Dubbo時,我們可以通過@Reference注解來注入對應(yīng)的擴展實現(xiàn),如:
在上述代碼中,我們指定了使用dubbo協(xié)議的DemoService接口的擴展實現(xiàn)。
我們也可以通過adaptive屬性來實現(xiàn)自適應(yīng)調(diào)用,如:
在上述代碼中,我們使用了adaptive屬性,并注入了Protocol類型的實例。這時,Dubbo框架會根據(jù)實際情況動態(tài)地生成對應(yīng)實現(xiàn)的代理類,并返回對應(yīng)的實例。
三、Dubbo的SPI擴展機制
1、什么是SPI擴展機制
Dubbo使用了Java的SPI(Service Provider Interface)擴展機制。SPI是JDK內(nèi)置的一種服務(wù)發(fā)現(xiàn)機制,其具體實現(xiàn)方式是在資源文件META-INF/services中通過名稱為SPI接口的全限定類名創(chuàng)建一個文本文件,在這個文本文件中可以寫入該SPI接口的實現(xiàn)類全限定類名,這樣可以實現(xiàn)動態(tài)加載實現(xiàn)類的目的。
?Dubbo中的SPI擴展機制能夠在不修改核心源代碼的前提下,通過修改配置文件或者實現(xiàn)自定義拓展類的方式來替換或增加核心功能。
下圖描述了 Dubbo SPI 擴展機制的工作流程:
SPI 擴展機制
上圖描述了 Dubbo SPI 擴展機制的工作流程,其中:
- 用戶向 Dubbo Framework 請求獲取 ExtensionLoader,ExtensionLoader 是 Dubbo SPI 擴展機制的核心類;
- Dubbo Framework 加載 ExtensionLoader,并返回給用戶;
- 用戶調(diào)用 ExtensionLoader 的方法;
- ExtensionLoader 根據(jù)指定的 Extension 接口,通過 SPI 機制加載 Extension 實現(xiàn);
- Extension 實現(xiàn)將被加載,ExtensionLoader 返回 Extension 實現(xiàn)給用戶;
2、SPI擴展機制的使用示例
首先,我們需要定義一個SPI擴展接口,讓Dubbo的擴展實現(xiàn)類都實現(xiàn)該接口。
示例代碼:
在接口上添加@SPI注解,指定該擴展的默認(rèn)實現(xiàn)類。
然后,我們需要在META-INF/services目錄下創(chuàng)建一個“接口全限定類名”的文件名的文件,文件中寫入我們實現(xiàn)的SPI擴展類的全限定類名。
比如我們需要同過實現(xiàn)PrintService接口來實現(xiàn)打印功能,那么我們在META-INF/services/目錄下創(chuàng)建一個名為“com.example.extension.PrintService”的文件,文件內(nèi)容為:
接下來,我們就可以通過Dubbo框架自動加載通過SPI機制注冊的實現(xiàn)類了。
示例代碼:
以上代碼中,我們使用Dubbo的擴展加載器ExtensionLoader來獲取PrintService接口的默認(rèn)實現(xiàn)類,然后調(diào)用該實現(xiàn)類的print()方法即可實現(xiàn)打印功能。
3、Dubbo的SPI擴展機制中自定義擴展點的實現(xiàn)示例
在Dubbo框架中,我們可以通過自定義擴展點來增強Dubbo的功能。
自定義擴展點需要實現(xiàn)Dubbo提供的ExtensionFactory接口,并在META-INF/dubbo/internal/?路徑下創(chuàng)建一個文件名為com.alibaba.dubbo.common.extension.ExtensionFactory的文件,文件中寫入擴展點實現(xiàn)類的全限定類名。
示例代碼:
在MyExtensionFactory中實現(xiàn)getExtension()方法,并根據(jù)type參數(shù)判斷獲取哪個擴展實現(xiàn)類。
在本示例中,我們僅僅實現(xiàn)了PrintService接口的實現(xiàn)類,因此只需要判斷type參數(shù)是否為PrintService類即可。
下一步,我們需要在META-INF/dubbo/internal/目錄下創(chuàng)建一個名為com.alibaba.dubbo.common.extension.ExtensionFactory的文件,文件內(nèi)容為我們實現(xiàn)的擴展點實現(xiàn)類全限定類名。
比如我們實現(xiàn)的擴展點實現(xiàn)類為com.example.extension.MyExtensionFactory?,那么我們就要在META-INF/dubbo/internal/目錄下創(chuàng)建一個名為com.alibaba.dubbo.common.extension.ExtensionFactory?的文件,并將文件內(nèi)容寫為com.example.extension.MyExtensionFactory。
最后,我們在程序中就可以使用自定義的擴展點了。示例代碼:
在以上示例代碼中,我們通過getExtension()方法來獲取PrintService接口的實現(xiàn)類。getExtension()方法中的參數(shù)為擴展點的name屬性,該屬性值默認(rèn)為“default”。
在本示例中我們將name的值設(shè)置為“console”,因此即使用了我們自定義的擴展點實現(xiàn)類。
四、Dubbo的自定義擴展點機制
1、什么是自定義擴展點機制
Dubbo的自定義擴展點機制是在SPI擴展機制的基礎(chǔ)上,增加了自定義擴展點的實現(xiàn)方式。通過Dubbo的擴展機制,我們可以通過配置文件切換Dubbo內(nèi)部的實現(xiàn)方式,但是對于用戶自己實現(xiàn)的功能模塊,如何進(jìn)行擴展呢?
這里就需要用到自定義擴展點機制了。
下圖是自定義擴展點機制的詳細(xì)時序圖:
自定義擴展點機制
在上圖中:
- 用戶首先將自己實現(xiàn)的擴展點注冊到Dubbo中;
- 然后在需要使用該擴展點的時候,Dubbo會根據(jù)擴展點的名稱進(jìn)行查找并返回相應(yīng)的擴展點實例;
- 通過這樣的機制,用戶可以靈活地擴展Dubbo的功能,同時也可以讓Dubbo更加適應(yīng)不同的業(yè)務(wù)場景。
自定義擴展點的核心思想就是:“面向接口編程,實現(xiàn)類實現(xiàn)接口,接口與實現(xiàn)類通過擴展點Binder關(guān)聯(lián)?!?/p>
其中,Binder的定義可以參考以下的代碼:
2、自定義擴展點機制的使用示例
為了更好地理解Dubbo的自定義擴展點機制,我們可以通過一個簡單的示例來演示其使用方法。假設(shè)我們有一個接口HelloService,我們想要通過自定義擴展點機制,為這個接口添加一個實現(xiàn)類。
首先,我們需要創(chuàng)建一個實現(xiàn)類HelloServiceImpl,該實現(xiàn)類需要實現(xiàn)HelloService接口。
接著,我們需要在resources/META-INF/dubbo目錄下創(chuàng)建一個名為com.xxx.HelloService的文件,該文件中需要指定HelloService接口的實現(xiàn)類名稱。
接下來,我們需要在代碼中獲取HelloService接口的實例。這可以通過以下方式實現(xiàn):
其中,getExtensionLoader()方法用于獲取擴展點的ExtensionLoader實例,getExtension()方法用于 獲取具體的擴展實例。
在上面的代碼中,我們通過“helloService”這個名稱獲取到了實現(xiàn)了HelloService接口的HelloServiceImpl實例,并調(diào)用了其中的sayHello()方法。
通過上述示例,我們可以看出,使用Dubbo的自定義擴展點機制非常簡單,只需要在配置文件中指定實現(xiàn)類的名稱,然后通過getExtensionLoader()和getExtension()方法獲取實例即可。
3、Dubbo的自定義擴展點機制的實現(xiàn)示例
在Dubbo的自定義擴展點機制中,最核心的是ExtensionLoader類和ExtensionFactory類。
其中,ExtensionLoader用于加載和管理擴展實例,ExtensionFactory用于創(chuàng)建擴展實例。
下面,我們將通過一個簡單的示例,演示Dubbo的自定義擴展點機制的具體實現(xiàn)方式。
首先,我們需要定義一個擴展點接口:
接著,我們需要實現(xiàn)該接口的一個實現(xiàn)類:
在這里,我們使用了@SPI注解來指定該擴展點的默認(rèn)實現(xiàn),如果配置文件中沒有指定其他實現(xiàn),則會使用該默認(rèn)實現(xiàn)。
接下來,我們需要創(chuàng)建一個名為com.xxx.HelloService的文件,該文件中需要指定擴展點接口的實現(xiàn)類名稱:
最后,我們需要在代碼中獲取HelloService接口的實例,這可以通過以下代碼實現(xiàn):
在上述代碼中,我們通過getExtensionLoader()方法獲取HelloService接口的ExtensionLoader實例,然后通過getExtension()方法獲取名為“helloWorld”的實現(xiàn)類實例,并調(diào)用其中的sayHello()方法。
五、Dubbo的過濾器擴展機制
1、Dubbo的過濾器機制概述
Dubbo的過濾器機制允許在調(diào)用前、調(diào)用后以及拋出異常時執(zhí)行一些額外的操作。過濾器在調(diào)用鏈路中按順序執(zhí)行,可以在過濾器中實現(xiàn)各種功能,例如:日志記錄、性能統(tǒng)計、權(quán)限控制等。
內(nèi)置過濾器
Dubbo中內(nèi)置了多個過濾器,包括:ClassLoader過濾器、Context過濾器、Generic過濾器、Echo過濾器、Token過濾器、AccessLog過濾器等。
下面是Dubbo的過濾器機制的時序圖:
上圖中:
- 服務(wù)消費者向服務(wù)提供者發(fā)送請求時,請求先經(jīng)過過濾器1;
- 如果過濾器1通過則進(jìn)一步經(jīng)過過濾器2;
- 如果過濾器2通過則進(jìn)一步經(jīng)過過濾器3;
- 如果過濾器3通過則將請求發(fā)送給服務(wù)提供者,服務(wù)提供者處理請求后將響應(yīng)返回給服務(wù)消費者,響應(yīng)也會經(jīng)過相同的過濾器鏈路;
- 如果任意一個過濾器拒絕請求,則直接返回錯誤響應(yīng)。
2、過濾器擴展機制的使用示例
Dubbo提供了擴展機制,可以在dubbo配置文件中配置過濾器,示例如下:
在上面的例子中,accessLogFilter表示需要使用的過濾器名稱,可以在dubbo配置文件中通過dubbo:filter標(biāo)簽進(jìn)行定義。
3、自定義過濾器的實現(xiàn)示例
要實現(xiàn)自定義過濾器,需要按照以下步驟進(jìn)行:
- 定義一個類實現(xiàn)org.apache.dubbo.rpc.Filter接口;
- 實現(xiàn)接口中的方法;
- 在META-INF/dubbo目錄下創(chuàng)建一個以org.apache.dubbo.rpc.Filter接口全限定名為名稱的文件,并在文件中添加自定義過濾器的類名。
下面是一個自定義的過濾器示例:
在上面的例子中,我們實現(xiàn)了一個MyFilter過濾器,并使用@Activate注解指定了它是一個provider端的過濾器,然后在invoke()方法中編寫自己的邏輯,最后調(diào)用invoker.invoke(invocation)方法來執(zhí)行調(diào)用鏈路中的下一個過濾器或服務(wù)。
六、Dubbo的負(fù)載均衡擴展機制
1、Dubbo的負(fù)載均衡擴展機制概述
負(fù)載均衡是分布式系統(tǒng)中的一個重要問題,它可以實現(xiàn)將請求分?jǐn)偟蕉鄠€服務(wù)提供者上,提高系統(tǒng)的并發(fā)能力和可用性。
Dubbo的負(fù)載均衡擴展機制允許用戶自定義負(fù)載均衡策略,實現(xiàn)更加靈活、適合特定場景的負(fù)載均衡算法。
Dubbo內(nèi)置了多種負(fù)載均衡算法,包括隨機、輪詢、最少活躍調(diào)用等。
下面是Dubbo的負(fù)載均衡擴展機制的時序圖:
負(fù)載均衡擴展機制
2、負(fù)載均衡擴展機制的使用示例
Dubbo的負(fù)載均衡擴展機制可以通過在服務(wù)提供方和服務(wù)消費方的配置文件中指定負(fù)載均衡策略來使用。
例如,在服務(wù)提供方的配置文件中可以添加以下配置:
在服務(wù)消費方的配置文件中可以添加以下配置:
這樣就可以實現(xiàn)使用Dubbo內(nèi)置的輪詢
3、自定義負(fù)載均衡策略的實現(xiàn)示例
用戶可以通過實現(xiàn)Dubbo的LoadBalance接口來自定義負(fù)載均衡策略。
以下是一個示例:
七、Dubbo的容錯機制擴展
1、Dubbo的容錯機制概述
Dubbo的容錯機制是指當(dāng)Dubbo服務(wù)調(diào)用出現(xiàn)異常時,Dubbo框架會根據(jù)預(yù)設(shè)的容錯機制進(jìn)行處理,以保證服務(wù)的高可用性。
Dubbo框架默認(rèn)提供了多種容錯機制,如Failover、Failfast、Failsafe、Failback、Forking等,也支持自定義容錯機制。
Dubbo的容錯機制通常是通過在客戶端代理層實現(xiàn)的,當(dāng)遠(yuǎn)程服務(wù)調(diào)用出現(xiàn)異常時,客戶端代理會根據(jù)預(yù)設(shè)的容錯機制進(jìn)行重試或處理,以保證服務(wù)的高可用性。
容錯機制
在Dubbo的容錯機制中,ClusterInvoker負(fù)責(zé)調(diào)用遠(yuǎn)程服務(wù),并進(jìn)行容錯處理。當(dāng)調(diào)用遠(yuǎn)程服務(wù)發(fā)生異常時,Dubbo會按照以下順序進(jìn)行容錯處理:
- ClusterInvoker處理異常;
- 如果ClusterInvoker處理異常失敗,則交由Router處理異常;
- 如果Router處理異常失敗,則交由LoadBalance處理異常;
- 如果LoadBalance處理異常失敗,則拋出異常給InvokerInvocationHandler,最終拋出給Consumer。同時,Dubbo還會將異常信息進(jìn)行監(jiān)控,并更新調(diào)用統(tǒng)計信息。
2、容錯機制擴展的使用示例
Dubbo默認(rèn)的容錯機制是Failover,即自動切換重試其他節(jié)點,達(dá)到容錯和負(fù)載均衡的效果。如果需要使用其他容錯機制,可以通過在服務(wù)提供方和服務(wù)消費方的配置文件中進(jìn)行配置。
例如,我們可以通過以下方式配置使用Failfast容錯機制:
在服務(wù)提供方的配置文件中增加如下配置:
在服務(wù)消費方的配置文件中增加如下配置:
這樣,在服務(wù)調(diào)用出現(xiàn)異常時,Dubbo框架會自動使用Failfast容錯機制進(jìn)行處理,即只進(jìn)行一次調(diào)用,若調(diào)用失敗則立即拋出異常,不進(jìn)行重試。
3、自定義容錯策略的實現(xiàn)示例
如果需要實現(xiàn)自定義的容錯策略,可以通過繼承org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker?類,并實現(xiàn)org.apache.dubbo.rpc.Invoker接口,來自定義容錯策略的實現(xiàn)。
例如,我們可以通過以下代碼實現(xiàn)一個自定義的容錯策略:
在實現(xiàn)自定義容錯策略后,需要在服務(wù)提供方和服務(wù)消費方的配置文件中進(jìn)行配置。
例如,在服務(wù)提供方的配置文件中增加如下配置:
在服務(wù)消費方的配置文件中增加如下配置:
這樣,在服務(wù)調(diào)用時,Dubbo框架會使用我們自定義的MyClusterInvoker容錯策略進(jìn)行處理。
八、Dubbo的擴展機制實踐
1、實現(xiàn)一個使用自定義擴展點、過濾器、負(fù)載均衡器和容錯機制的 Dubbo 服務(wù)
在這個實踐中,我們將實現(xiàn)一個使用自定義擴展點、過濾器、負(fù)載均衡器和容錯機制的 Dubbo 服務(wù)。
2、首先,我們需要定義一個服務(wù)接口。
例如,我們可以定義一個名為 SomeService 的服務(wù)接口,如下所示:
3、然后,我們需要實現(xiàn)該服務(wù)接口。
例如,我們可以實現(xiàn)一個名為 SomeServiceImpl 的服務(wù)實現(xiàn)類,如下所示:
4、接下來,我們需要配置 Dubbo 的擴展點、過濾器、負(fù)載均衡器和容錯機制。
例如,我們可以在服務(wù)提供方和服務(wù)消費方的配置文件中進(jìn)行如下配置:
其中,com.example.extension.MyProtocol? 是一個自定義的 Dubbo 協(xié)議擴展點實現(xiàn)類,com.example.filter.MyProviderFilter? 和 com.example.filter.MyConsumerFilter? 是自定義的 Dubbo 過濾器實現(xiàn)類,com.example.loadbalance.MyLoadBalance? 是一個自定義的 Dubbo 負(fù)載均衡器實現(xiàn)類,com.example.cluster.MyCluster 是一個自定義的 Dubbo 容錯機制實現(xiàn)類。
5、最后,我們可以使用 Dubbo 的 API 在客戶端調(diào)用該服務(wù)。
例如,我們可以使用如下代碼在客戶端調(diào)用該服務(wù):
這樣,我們就實現(xiàn)了一個使用自定義擴展點、過濾器、負(fù)載均衡器和容錯機制的 Dubbo 服務(wù)。
本文轉(zhuǎn)載自微信公眾號「哪吒編程」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系哪吒編程公眾號。