阿里大佬帶你一次性吃透基于Spring Cloud動態(tài)配置實現(xiàn)動態(tài)數(shù)據(jù)源

基于Spring Cloud動態(tài)配置實現(xiàn)動態(tài)數(shù)據(jù)源
筆者在一些項目中并未使用Sentinel提供的任何一種實現(xiàn)動態(tài)數(shù)據(jù)源的方式,而是選擇自己實現(xiàn)動態(tài)數(shù)據(jù)源,因為這些項目被部署在Kubernetes平臺上,所以可以利用Kubernetes提供的ConfigMap資源存儲限流、熔斷降級等規(guī)則,又因為Spring Cloud Kubernetes提供了SpringCloud動態(tài)配置接口的實現(xiàn),所以我們不需要關(guān)心如何讀取ConfigMap資源。
本節(jié)以實現(xiàn)FlowRule動態(tài)配置為例,詳細介紹如何基于Spring Cloud動態(tài)配置實現(xiàn)動態(tài)數(shù)據(jù)源,主要分為5個步驟。
第一步,定義一個用于裝載動態(tài)限流規(guī)則配置的FlowRuleProps類,代碼如下。

第二步,定義限流規(guī)則轉(zhuǎn)換器FlowRuleConverter,將限流規(guī)則配置轉(zhuǎn)換為FlowRule集合,代碼如下。

第三步,定義限流規(guī)則動態(tài)數(shù)據(jù)源FlowRuleDataSource,繼承AbstractDataSource抽象類,并實現(xiàn)readSource方法,代碼如下。readSource方法只需要實現(xiàn)獲取FlowRuleProps實例并返回即可。

第四步,增強FlowRuleDataSource,使FlowRuleDataSource能夠監(jiān)聽到配置改變,代碼如下。

? 增強一:實現(xiàn)Spring InitializingBean接口的afterPropertiesSet方法,在數(shù)據(jù)源對象創(chuàng)建時,初始化加載一次規(guī)則配置。
? 增強二:實現(xiàn)SpringApplicationListener接口的onApplicationEvent方法,監(jiān)聽動態(tài)配置改變事件(
RefreshScopeRefreshedEvent)。
在監(jiān)聽到
RefreshScopeRefreshedEvent事件時,首先調(diào)用loadConfig方法加載所有限流規(guī)則配置,然后調(diào)用getProperty方法獲取SentinelProperty實例,最后調(diào)用SentinelProperty實例的updateValue方法通知FlowRuleManager的監(jiān)聽器更新限流規(guī)則配置。
第五步,定義一個ApplicationRunner,在Spring容器刷新完成后,將FlowRuleDataSource實例的SentinelProperty實例注冊給FlowRuleManager,代碼如下。

提示:在調(diào)用FlowRuleManager#register2Property方法將FlowRuleDataSource實例的SentinelProperty實例注冊給FlowRuleManager時,F(xiàn)lowRuleManager會自動給該SentinelProperty實例注冊一個FlowPropertyListener實例。
至此,一個基于Spring Cloud動態(tài)配置實現(xiàn)的限流規(guī)則動態(tài)數(shù)據(jù)源就已經(jīng)完成,整個工作流程如下。
(1)當動態(tài)配置改變時,Spring
Cloud會發(fā)送
RefreshScopeRefreshedEvent事件,
FlowRuleDataSource的onApplicationEvent方法會被調(diào)用。
(2)FlowRuleDataSource調(diào)用loadConfig方法獲取最新的配置。
(3)FlowRuleDataSource#loadConfig方法調(diào)用readSource方法獲取FlowRuleProps實例,此時的FlowRuleProps實例已經(jīng)裝載了最新的配置。
(4)FlowRuleDataSource#loadConfig方法調(diào)用FlowRuleConverter實例的convert方法將FlowRuleProps實例轉(zhuǎn)換為FlowRule集合。
(5)FlowRuleDataSource調(diào)用自身的SentinelProperty實例的updateValue方法通知所有監(jiān)聽器,并攜帶新的規(guī)則配置。
(6)FlowPropertyListener的configUpdate方法被調(diào)用,F(xiàn)lowPropertyListener在configUpdate方法中更新FlowRuleManager緩存的限流規(guī)則配置。
提示:Sentinel實現(xiàn)動態(tài)數(shù)據(jù)源的整體框架的設(shè)計值得我們學習,如數(shù)據(jù)轉(zhuǎn)換器、監(jiān)聽器。