Java?Dubbo服務(wù)調(diào)用擴(kuò)展點(diǎn)Filter使用教程
擴(kuò)展點(diǎn)介紹

如上圖所示,從服務(wù)調(diào)用的角度來(lái)看,Dubbo 在鏈路中提供了豐富的擴(kuò)展點(diǎn),覆蓋了負(fù)載均衡方式、選址前后的攔截器、服務(wù)端處理攔截器等。 簡(jiǎn)單來(lái)說(shuō) Dubbo 發(fā)起遠(yuǎn)程調(diào)用的時(shí)候,主要工作流程可以分為消費(fèi)端和服務(wù)端兩個(gè)部分。
消費(fèi)端的工作流程如下:
通過(guò) Stub 接收來(lái)自用戶的請(qǐng)求,并且封裝在 Invocation 對(duì)象中
將 Invocation 對(duì)象傳遞給 ClusterFilter(擴(kuò)展點(diǎn))做選址前的請(qǐng)求預(yù)處理,如請(qǐng)求參數(shù)的轉(zhuǎn)換、請(qǐng)求日志記錄、限流等操作都是在此階段進(jìn)行的
將 Invocation 對(duì)象傳遞給 Cluster(擴(kuò)展點(diǎn))進(jìn)行集群調(diào)用邏輯的決策,如快速失敗模式、安全失敗模式等決策都是在此階段進(jìn)行的
- Cluster 調(diào)用 Directory 獲取所有可用的服務(wù)端地址信息
- Directory 調(diào)用 StateRouter(擴(kuò)展點(diǎn),推薦使用) 和 Router(擴(kuò)展點(diǎn)) 對(duì)服務(wù)端的地址信息進(jìn)行路由篩選,此階段主要是從全量的地址信息中篩選出本次調(diào)用允許調(diào)用到的目標(biāo),如基于打標(biāo)的流量路由就是在此階段進(jìn)行的
- Cluster 獲得從 Directory 提供的可用服務(wù)端信息后,會(huì)調(diào)用 LoadBalance (擴(kuò)展點(diǎn))從多個(gè)地址中選擇出一個(gè)本次調(diào)用的目標(biāo),如隨機(jī)調(diào)用、輪詢調(diào)用、一致性哈希等策略都是在此階段進(jìn)行的
- Cluster 獲得目標(biāo)的 Invoker 以后將 Invocation 傳遞給對(duì)應(yīng)的 Invoker,并等待返回結(jié)果,如果出現(xiàn)報(bào)錯(cuò)則執(zhí)行對(duì)應(yīng)的決策(如快速失敗、安全失敗等)
經(jīng)過(guò)上面的處理,得到了帶有目標(biāo)地址信息的 Invoker,會(huì)再調(diào)用 Filter(擴(kuò)展點(diǎn))進(jìn)行選址后的請(qǐng)求處理(由于在消費(fèi)端側(cè)創(chuàng)建的 Filter 數(shù)量級(jí)和服務(wù)端地址量級(jí)一致,如無(wú)特殊需要建議使用 ClusterFilter 進(jìn)行擴(kuò)展攔截,以提高性能)
最后 Invocation 會(huì)被通過(guò)網(wǎng)絡(luò)發(fā)送給服務(wù)端
服務(wù)端的工作流程如下:
服務(wù)端通信層收到請(qǐng)求以后,會(huì)將請(qǐng)求傳遞給協(xié)議層構(gòu)建出 Invocation
將 Invocation 對(duì)象傳遞給 Filter (擴(kuò)展點(diǎn))做服務(wù)端請(qǐng)求的預(yù)處理,如服務(wù)端鑒權(quán)、日志記錄、限流等操作都是在此階段進(jìn)行的
將 Invocation 對(duì)象傳遞給動(dòng)態(tài)代理做真實(shí)的服務(wù)端調(diào)用
介紹完擴(kuò)展點(diǎn)后,下面以攔截?cái)U(kuò)展點(diǎn)為例介紹具體使用
攔截點(diǎn)
官方接口: org.apache.dubbo.rpc.Filter
@SPI(scope = ExtensionScope.MODULE)
public interface Filter extends BaseFilter {
}
在項(xiàng)目中實(shí)現(xiàn)該接口,自定義邏輯:
@Slf4j
@Activate(group = CommonConstants.CONSUMER)
public class ParamFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
// 這里可以獲取到消費(fèi)者請(qǐng)求的相關(guān)信息,如服務(wù)名、請(qǐng)求的方法名、以及請(qǐng)求的參數(shù)
// 實(shí)際應(yīng)用:做一些參數(shù)檢查以及轉(zhuǎn)換等等操作
log.info("Service-Name: " + invocation.getServiceName() + " Method: " + invocation.getMethodName() + " Parameter: " + Arrays.toString(invocation.getArguments()));
// 將請(qǐng)求發(fā)送給服務(wù)端
return invoker.invoke(invocation);
}
}
編寫(xiě)Filter的配置文件:

文件名:org.apache.dubbo.rpc.Filter
內(nèi)容:
MyFilter=com.mxf.filter.ParamFilter
MyFilter: 是自定義Filter的一個(gè)別名,可以自定義
在application.yaml中配置該接口:
dubbo:
application:
name: shop-service-consumer
protocol:
name: dubbo
port: -1
registry:
id: nacos-registry
address: nacos://192.168.11.233:8848
config-center:
address: nacos://192.168.11.233:8848
metadata-report:
address: nacos://192.168.11.233:8848
consumer: #在消費(fèi)端的攔截?cái)U(kuò)展點(diǎn)
filter: MyFilter # 注意名稱(chēng)要和簽名定義的一致
重啟項(xiàng)目演示
可以使用Postman請(qǐng)求相關(guān)接口,就可以看到輸出日志:
2022-11-23 11:39:36.463 INFO 8988 --- [nio-8082-exec-1] com.mxf.filter.ParamFilter : Service-Name: com.mxf.service.ShopService Method: queryByName Parameter: [xiao]

可以看到在消費(fèi)端自定義的攔截?cái)U(kuò)展點(diǎn)已經(jīng)生效,可以獲取到相關(guān)信息
Dubbo實(shí)現(xiàn)負(fù)載均衡的擴(kuò)展
官方提供的接口:

RandomLoadBalance:隨機(jī)策略的LB
RoundRobinLoadBalance:輪詢策略的LB
LeastActiveLoadBalance:最少活躍調(diào)用數(shù)策略的LB:舉例有兩臺(tái)服務(wù)器,一臺(tái)正在處理的任務(wù)數(shù)很多也就是負(fù)載高,那么當(dāng)前負(fù)載策略就會(huì)盡量少的給這臺(tái)服務(wù)器分配任務(wù);反之,如果一臺(tái)服務(wù)器處理的任務(wù)數(shù)少,就盡量?jī)?yōu)先給它分配任務(wù)。
ConsistentHashLoadBalance:一致性Hash策略的LB:。一致性Hash,相同參數(shù)的請(qǐng)求總是發(fā)到同一提供者,當(dāng)某一臺(tái)提供者掛時(shí),原本發(fā)往該提供者的請(qǐng)求,基于虛擬節(jié)點(diǎn),平攤到其它提供者,不會(huì)引起劇烈變動(dòng)。
ShortestResponseLoadBalance:最短響應(yīng)優(yōu)先策略的LB
除了以上Dubbo提供的五種默認(rèn)實(shí)現(xiàn)的負(fù)載均衡策略,也可以自定義負(fù)載均衡策略,只要實(shí)現(xiàn)Dubbo提供的LoadBalance接口,自定義實(shí)現(xiàn)select即可:
@SPI(RandomLoadBalance.NAME)
public interface LoadBalance {
/**
* select one invoker in list.
*
* @param invokers invokers.
* @param url refer url
* @param invocation invocation.
* @return selected invoker.
*/
@Adaptive("loadbalance")
<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;
}用法:以輪詢策略為例
第一步編寫(xiě)配置文件:

文件名:org.apache.dubbo.rpc.cluster.LoadBalance
RRLB=org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
RRLB是自定義的負(fù)載均衡名稱(chēng)
在application.yaml中配置LB:
dubbo:
consumer: # 在消費(fèi)端的LB
loadbalance: RRLB
OK,到此配置完成,當(dāng)啟動(dòng)多個(gè)服務(wù)提供者,用一個(gè)消費(fèi)者去調(diào)用,就是采取輪詢的策略均勻請(qǐng)求到服務(wù)提供者上
其余四種實(shí)現(xiàn)方式一樣。
到此這篇關(guān)于Java Dubbo服務(wù)調(diào)用擴(kuò)展點(diǎn)Filter使用教程的文章就介紹到這了,更多相關(guān)Java Filter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于java web獲取網(wǎng)頁(yè)訪問(wèn)次數(shù)代碼實(shí)例
這篇文章主要介紹了基于java web獲取網(wǎng)頁(yè)訪問(wèn)次數(shù)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
Java利用TreeUtils工具類(lèi)實(shí)現(xiàn)列表轉(zhuǎn)樹(shù)
在開(kāi)發(fā)過(guò)程中,總有列表轉(zhuǎn)樹(shù)的需求,幾乎是項(xiàng)目的標(biāo)配,有沒(méi)有一種通用且跨項(xiàng)目的解決方式呢?本文將基于Java8的Lambda?表達(dá)式和Stream等知識(shí),使用TreeUtils工具類(lèi)實(shí)現(xiàn)一行代碼完成列表轉(zhuǎn)樹(shù)這一通用型需求,需要的可以參考一下2022-11-11
mybatis通過(guò)XML的方式拼接動(dòng)態(tài)sql
動(dòng)態(tài)SQL是一種在運(yùn)行時(shí)構(gòu)造和執(zhí)行SQL語(yǔ)句的技術(shù),這篇文章主要為大家介紹了mybatis如何通過(guò)XML的方式拼接動(dòng)態(tài)sql,有需要的小伙伴可以參考一下2024-12-12
詳解SpringBoot多跨域請(qǐng)求的支持(JSONP)
跨域是很多項(xiàng)目需要遇到的文章,本篇文章主要介紹了詳解SpringBoot多跨域請(qǐng)求的支持(JSONP),具有一定的參考價(jià)值,有興趣的可以了解一下2017-04-04
java實(shí)現(xiàn)外賣(mài)訂餐系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)外賣(mài)訂餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01
解析Spring Boot 如何讓你的 bean 在其他 bean&n
在 SpringBoot 中如何讓自己的某個(gè)指定的 Bean 在其他 Bean 前完成被 Spring 加載?我聽(tīng)到這個(gè)問(wèn)題的第一反應(yīng)是,為什么會(huì)有這樣奇怪的需求?下面小編給大家分析下Spring Boot 如何讓你的 bean 在其他 bean 之前完成加載 ,感興趣的朋友一起看看吧2024-01-01

