[學習]sentinel中的DatatSource(二) WritableDataSource

sentinel是今年阿里開源的高可用防禦的流量管理框架。html

git地址:https://github.com/alibaba/Sentinel前端

wiki:https://github.com/alibaba/Sentinel/wikijava

FAQ:https://github.com/alibaba/Sentinel/wiki/FAQgit

--------------------------------------------------------------------------------------------------------------------------------------------------------github

[學習]sentinel中的DatatSource(一) ReadableDataSource數據庫

在上一篇中學習了sentinel中的ReadableDataSource,本篇來學習和梳理下WritableDataSource。json

--------------------------------------------------------------------------------------------------------------------------------------------------------瀏覽器

WritableDataSource顧名思義,是可寫的數據源,在sentinel-datasource-extension模塊下,com.alibaba.csp.sentinel.datasource包:併發

接口有兩個方法:框架

write是將數據寫到數據源中,進行保存;

close是關閉datasource相關的資源。

 

該包下提供了一個實現類,FileWritableDataSource,使用文件做爲數據源。

先看屬性,定義了

configEncoder用於將T類型轉換爲String類型;

file用於肯定數據源文件;

charset字符集用於區分編碼格式,默認是UTF-8;

lock用戶寫文件時加鎖,避免併發寫問題;

 

接着是構造函數,能夠看到提供了3種重載來方便構造;

在最後實際調用的構造函數中,首先驗證了參數合法性,包括:文件非空、不是目錄、轉換器和字符集非空;而後將參數保存在類的屬性中;

 

最後是實現WritableDataSource接口的兩個方法:

write方法首先經過lock加鎖,調用轉換器configEncoder的convert方法將T類型轉換爲String,再調用java io將String寫入文件,最後釋放鎖;

close方法中,因沒有釋放的資源,不做任何處理。

 

在IDEA裏,按住Ctrl鍵,點擊FileWritableDataSource<T>類名,發現FileDataSourceInit類用到了它

該類位於sentinel-demo模塊下的sentinel-demo-dynamic-file-rule,是一個FileDatasource的demo演示:

咱們看到FileDataSourceInit實現了InitFunc接口,這是Sentinel 的 InitFunc SPI 擴展接口。

參考:https://github.com/alibaba/Sentinel/wiki/動態規則擴展

看代碼中如何構造FileWritableDataSource的:

flowRulePath是流控規則文件的路徑;

encodeJson是前文提到的轉換器,這裏用了jdk1.8雙冒號的語法,使用用fastjson提供的靜態方法JSON.toJSONString將List<Rule>轉換爲String;

注意到,構造好WritableDataSource後,用WritableDataSourceRegistry.registerFlowDataSource(wds)進行了註冊;

 

WritableDataSourceRegistry類位於sentinel-transport-common模塊裏,裏面保存了flow、degrade、system、authority四種規則的WritableDataSource,並提供了註冊(register)和獲取(get)的靜態方法;

一樣可使用剛纔Ctrl+左鍵的方式繼續跟下去,找到它的調用。限於篇幅就暫不展開了。有興趣的讀者能夠試試。

 

WritableDataSource用於寫規則數據至數據源,跟sentinel-dashborad結合使用。

以流控規則爲例,數據流轉大體以下:

1. 在sentinel-dashboard界面中新增、修改、刪除流控規則

2.dashborad中FlowController接收前端界面請求,先調用InMemFlowRuleStore的repository將內存中的數據更新,而後用SentinelApiClient經過http請求的方式與sentinel客戶端(接入sentinel的應用)進行交互

   http://ip:port/setRulesPath?type=flowRuleType&data=xxx

3.sentinel客戶端的ModifyRulesCommandHandler處理請求,經過FlowRuleManager.loadRules(flowRules)從新加載規則,再調用已註冊的WritableDataSource的write方法,將規則數據寫至數據源

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

咱們來看看FileDataSource的demo。

FileDataSourceDemo類listenRules方法,構造了3種規則的FileRefreshableDataSource。

FlowQpsRunner類中的資源名稱爲"abc",

在FlowRule.json文件中有一條該資源的流控規則:

能夠看到是controlBehavior=0默認快速失敗方式,grade=1的QPS方法,count=20.0。 該規則表示超過20QPS/秒進行快速失敗限流。

運行FileDataSourceDemo類的main方法:

能夠看到,經過的qps大體在20左右。

 

前文提到FileWritableDataSource在FileDataSourceInit類中構造。demo中使用了FileRefreshableDataSource讀取規則。

咱們來把FileWritableDataSource用起來試試。

參考官方文檔,在demo工程的resources目錄下,增長META-INF/services目錄結構,增長com.alibaba.csp.sentinel.init.InitFunc文件 // 能夠從sentinel-transport-simple-http模塊中的resources目錄拷貝

文件內容爲com.alibaba.csp.sentinel.demo.file.rule.FileDataSourceInit

 

因FileDataSourceInit中已經有ReadableDataSource和WritableDataSource構造了,所以咱們將FileDataSourceDemo中加載規則的代碼註釋掉;

增長啓動參數-Dproject.name=FileDataSourceDemo -Dcsp.sentinel.dashboard.server=localhost:8080;

把dashboard先啓起來;

demo中的FlowQpsRunner類,運行是100秒,爲了有更充裕的時間觀察、debug而程序不退出,咱們把它改大一點:

FileDataSourceInit加載的文件路徑是用戶目錄下的/sentinel/rules/flowRule.json

所以咱們把目錄結構按此建好,拷貝resources下的FlowRule.json文件過去

而後運行FileDataSourceDemo,啓動後觀察console輸出:

因爲FlowRule.json文件中abc資源的count=20,能夠看到pass的qps在20左右;

瀏覽器打開控制檯http://localhost:8080,在機器列表菜單下,能夠看到應用已經在列表中顯示

點擊流控規則,

能夠看到資源abc的規則閾值設置爲20,點擊編輯把閾值改爲5,點保存;

再觀察console的輸出:

pass的qps已經從20,降到了5左右;

打開用戶目錄下的/sentinel/rules/flowRule.json文件,能夠看到json中的abc資源的count已變成了5;

因而可知,FileWritableDataSource是生效了的;

而且這種方式結合控制檯能夠很方便的在界面配置規則,並持久化到文件。

 

打開用戶目錄/logs/csp中的最近修改的record.log.pidxxxx文件:

2018-09-13 13:13:25 [FlowRuleManager] Flow rules received: {abc1=[FlowRule{resource=abc1, limitApp=default, grade=1, count=20.0, strategy=0, refResource=null, controlBehavior=0, warmUpPeriodSec=10, maxQueueingTimeMs=500, controller=com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController@301ad2}], abc=[FlowRule{resource=abc, limitApp=default, grade=1, count=5.0, strategy=0, refResource=null, controlBehavior=0, warmUpPeriodSec=10, maxQueueingTimeMs=500, controller=com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController@150daa0}]}
2018-09-13 13:13:25 [FileWritableDataSource] Writing to file C:\Users\five\sentinel\rules\flowRule.json: [{"controlBehavior":0,"count":20.0,"grade":1,"limitApp":"default","maxQueueingTimeMs":500,"resource":"abc1","strategy":0,"warmUpPeriodSec":10},{"controlBehavior":0,"count":5.0,"grade":1,"limitApp":"default","maxQueueingTimeMs":500,"resource":"abc","strategy":0,"warmUpPeriodSec":10}]

看到修改的規則已被FlowRuleManager從新加載,而且經過FileWritableDataSource寫至到了flowRule.json文件:)

--------------------------------------------------------------------------------------------------------------------------------------------------------

總結:

1. WritableDataSource提供了咱們將sentinel內存中規則寫回數據源的接口,控制檯編輯規則時,除了經過http方式更新sentinel客戶端的規則,還會調用WritableDataSourceRegistry註冊的WritableDataSource的write方法;

2. 如Jdbc數據庫、File文件等可寫入的數據源,實現定製的WritableDataSource接口,能夠方便咱們配合控制檯界面來配置規則;

3. 不一樣類型的數據源,根據Pull、Push模式,對控制檯、ReadableDataSource、WritableDataSource可根據須要進行不一樣的定製擴展。

--------------------------------------------------------------------------------------------------------------------------------------------------------

思考:

1.WritableDataSource的write默認是全量更新數據,單個應用規則多時可能有性能問題,考慮如何區分出有變更的增量規則,將增量數據寫入數據源;

2.sentinel的控制檯界面,規則是按應用、ip、端口來單獨配置的,設計持久化結構時須要考慮。

 --------------------------------------------------------------------------------------------------------------------------------------------------------

參考:

https://github.com/alibaba/Sentinel/wiki/動態規則擴展

https://github.com/alibaba/Sentinel/wiki/控制檯

相關文章
相關標籤/搜索