Java?Dubbo服務(wù)調(diào)用擴展點Filter使用教程
擴展點介紹
如上圖所示,從服務(wù)調(diào)用的角度來看,Dubbo 在鏈路中提供了豐富的擴展點,覆蓋了負(fù)載均衡方式、選址前后的攔截器、服務(wù)端處理攔截器等。 簡單來說 Dubbo 發(fā)起遠(yuǎn)程調(diào)用的時候,主要工作流程可以分為消費端和服務(wù)端兩個部分。
消費端的工作流程如下:
通過 Stub 接收來自用戶的請求,并且封裝在 Invocation 對象中
將 Invocation 對象傳遞給 ClusterFilter(擴展點)做選址前的請求預(yù)處理,如請求參數(shù)的轉(zhuǎn)換、請求日志記錄、限流等操作都是在此階段進(jìn)行的
將 Invocation 對象傳遞給 Cluster(擴展點)進(jìn)行集群調(diào)用邏輯的決策,如快速失敗模式、安全失敗模式等決策都是在此階段進(jìn)行的
- Cluster 調(diào)用 Directory 獲取所有可用的服務(wù)端地址信息
- Directory 調(diào)用 StateRouter(擴展點,推薦使用) 和 Router(擴展點) 對服務(wù)端的地址信息進(jìn)行路由篩選,此階段主要是從全量的地址信息中篩選出本次調(diào)用允許調(diào)用到的目標(biāo),如基于打標(biāo)的流量路由就是在此階段進(jìn)行的
- Cluster 獲得從 Directory 提供的可用服務(wù)端信息后,會調(diào)用 LoadBalance (擴展點)從多個地址中選擇出一個本次調(diào)用的目標(biāo),如隨機調(diào)用、輪詢調(diào)用、一致性哈希等策略都是在此階段進(jìn)行的
- Cluster 獲得目標(biāo)的 Invoker 以后將 Invocation 傳遞給對應(yīng)的 Invoker,并等待返回結(jié)果,如果出現(xiàn)報錯則執(zhí)行對應(yīng)的決策(如快速失敗、安全失敗等)
經(jīng)過上面的處理,得到了帶有目標(biāo)地址信息的 Invoker,會再調(diào)用 Filter(擴展點)進(jìn)行選址后的請求處理(由于在消費端側(cè)創(chuàng)建的 Filter 數(shù)量級和服務(wù)端地址量級一致,如無特殊需要建議使用 ClusterFilter 進(jìn)行擴展攔截,以提高性能)
最后 Invocation 會被通過網(wǎng)絡(luò)發(fā)送給服務(wù)端
服務(wù)端的工作流程如下:
服務(wù)端通信層收到請求以后,會將請求傳遞給協(xié)議層構(gòu)建出 Invocation
將 Invocation 對象傳遞給 Filter (擴展點)做服務(wù)端請求的預(yù)處理,如服務(wù)端鑒權(quán)、日志記錄、限流等操作都是在此階段進(jìn)行的
將 Invocation 對象傳遞給動態(tài)代理做真實的服務(wù)端調(diào)用
介紹完擴展點后,下面以攔截擴展點為例介紹具體使用
攔截點
官方接口: org.apache.dubbo.rpc.Filter
@SPI(scope = ExtensionScope.MODULE) public interface Filter extends BaseFilter { }
在項目中實現(xiàn)該接口,自定義邏輯:
@Slf4j @Activate(group = CommonConstants.CONSUMER) public class ParamFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { // 這里可以獲取到消費者請求的相關(guān)信息,如服務(wù)名、請求的方法名、以及請求的參數(shù) // 實際應(yīng)用:做一些參數(shù)檢查以及轉(zhuǎn)換等等操作 log.info("Service-Name: " + invocation.getServiceName() + " Method: " + invocation.getMethodName() + " Parameter: " + Arrays.toString(invocation.getArguments())); // 將請求發(fā)送給服務(wù)端 return invoker.invoke(invocation); } }
編寫Filter的配置文件:
文件名:org.apache.dubbo.rpc.Filter
內(nèi)容:
MyFilter=com.mxf.filter.ParamFilter
MyFilter: 是自定義Filter的一個別名,可以自定義
在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: #在消費端的攔截擴展點 filter: MyFilter # 注意名稱要和簽名定義的一致
重啟項目演示
可以使用Postman請求相關(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]
可以看到在消費端自定義的攔截擴展點已經(jīng)生效,可以獲取到相關(guān)信息
Dubbo實現(xiàn)負(fù)載均衡的擴展
官方提供的接口:
RandomLoadBalance:隨機策略的LB
RoundRobinLoadBalance:輪詢策略的LB
LeastActiveLoadBalance:最少活躍調(diào)用數(shù)策略的LB:舉例有兩臺服務(wù)器,一臺正在處理的任務(wù)數(shù)很多也就是負(fù)載高,那么當(dāng)前負(fù)載策略就會盡量少的給這臺服務(wù)器分配任務(wù);反之,如果一臺服務(wù)器處理的任務(wù)數(shù)少,就盡量優(yōu)先給它分配任務(wù)。
ConsistentHashLoadBalance:一致性Hash策略的LB:。一致性Hash,相同參數(shù)的請求總是發(fā)到同一提供者,當(dāng)某一臺提供者掛時,原本發(fā)往該提供者的請求,基于虛擬節(jié)點,平攤到其它提供者,不會引起劇烈變動。
ShortestResponseLoadBalance:最短響應(yīng)優(yōu)先策略的LB
除了以上Dubbo提供的五種默認(rèn)實現(xiàn)的負(fù)載均衡策略,也可以自定義負(fù)載均衡策略,只要實現(xiàn)Dubbo提供的LoadBalance接口,自定義實現(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; }
用法:以輪詢策略為例
第一步編寫配置文件:
文件名:org.apache.dubbo.rpc.cluster.LoadBalance
RRLB=org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
RRLB是自定義的負(fù)載均衡名稱
在application.yaml中配置LB:
dubbo: consumer: # 在消費端的LB loadbalance: RRLB
OK,到此配置完成,當(dāng)啟動多個服務(wù)提供者,用一個消費者去調(diào)用,就是采取輪詢的策略均勻請求到服務(wù)提供者上
其余四種實現(xiàn)方式一樣。
到此這篇關(guān)于Java Dubbo服務(wù)調(diào)用擴展點Filter使用教程的文章就介紹到這了,更多相關(guān)Java Filter內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
request如何獲取完整url(包括域名、端口、參數(shù))
這篇文章主要介紹了request如何獲取完整url(包括域名、端口、參數(shù))問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12MyBatis的通俗理解:SqlSession.getMapper()源碼解讀
這篇文章主要介紹了MyBatis的通俗理解:SqlSession.getMapper()源碼解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03Java虛擬機內(nèi)存分配與回收策略問題精細(xì)解讀
Java技術(shù)體系中所提倡的自動內(nèi)存管理最終可以歸結(jié)為自動化地解決了兩個問題:給對象分配內(nèi)存以及回收分配給對象的內(nèi)存,本文讓我們來詳細(xì)了解2021-11-11