[Soul 源碼之旅] 1.5 Soul數(shù)據(jù)同步 (Zookeeper)

1.5.1 Soul Admin Zookeeper 發(fā)布更新

我們還是從上次的入口進(jìn)來 DataChangedEventDispatcher 的 onApplicationEvent 方法,我們開啟Zookeeper發(fā)送數(shù)據(jù)后,在 DataSyncConfiguration 中定義假如存在soul.sync.zookeeper 參數(shù)則會注入 zookeeperDataChangedListener 監(jiān)聽器。


image.png

這里使用到@Import注解,該注解主要作用是用來導(dǎo)入@Configuration注解的配置類,這里我們只有但含有 Zookeeper 的配置項才可以注入ZookeeperListener 同理也只有在這個時候才會注入 ZookeeperConfiguration 類。我們看 ZookeeperProperties 類 @ConfigurationProperties 注解是假如沒有@Component 注解配合,Spring 是不會自動作為Bean注入的,需要使用@EnableConfigurationProperties 把使用 @ConfigurationProperties 的類進(jìn)行了一次注入。


image.png

這里會根據(jù) Zookeeper 的 Url new 了一個ZKClinet 作為后面數(shù)據(jù)寫入的客戶端。zookeeperDataChangedListener 再根據(jù)注入的這個ZkClient ,這里還有一個類就是 ZookeeperDataInit 它主要是實現(xiàn)了CommandLineRunner 這是 Spring 中程序啟動之前執(zhí)行任何任務(wù),這里是判斷zk 是否存在需要監(jiān)聽的路徑,假如沒有則調(diào)用 SyncDataService 的syncAll 方法,這里和我們看到的WebSocket是一致的,最終將 Plugin ,Selector 和 Rule 三種數(shù)據(jù)通知個對應(yīng)的 Listener , 這里就是調(diào)用到剛剛初始化完成的 zookeeperDataChangedListener 。
image.png

我們以Selector 為例,這里最終調(diào)用 createSelector 進(jìn)行創(chuàng)建。


create

先創(chuàng)建對應(yīng)的path,然后再根據(jù)Selector 的id 生產(chǎn)下一級路徑,最后將Selector 的 data 寫入該節(jié)點。
selector

我們使用zookeeperInspect 查看,這里的數(shù)據(jù)已經(jīng)寫入Zookeeper ,最終這里寫入了我們數(shù)據(jù)庫所有的數(shù)據(jù)。這里是直接使用 java 內(nèi)置的序列化方式。
image.png

1.5.2 Soul BootStrap Zookeeper 同步數(shù)據(jù)

Soul BootStrap 使用Zookeeper 同步數(shù)據(jù)的主要配置類是 ZookeeperSyncDataConfiguration ,通過ZookeeperConfig 自動化生產(chǎn) Zkclient。


image.png

ZookeeperSyncDataConfiguration 初始化主要做了三件事,就是綁定 data meta 和 auth 數(shù)據(jù)的監(jiān)聽事件。我們從 selector 作為出發(fā)點,所以觸發(fā)的方法是 watcherData。


image.png

首先Soul 獲取了/soul/plugin 路徑下的所有插件信息。然后遍歷每個插件,調(diào)用 watcherAll 方法,監(jiān)聽該插件的 Plugin Selector 和 Rule 信息。
image.png

我們看一下Hystrix 插件的 watchSelector 方法,它先看該節(jié)點下是否存在插件的selector 數(shù)據(jù),假如有則將所有數(shù)據(jù)拿回來進(jìn)行遍歷。


image.png

然后更新本地內(nèi)存,這里主要是通知各個 plugin 插件更新內(nèi)存數(shù)據(jù)。這里通過 pluginDataSubscriber 拿到各個插件數(shù)據(jù)處理的 Handler 進(jìn)行數(shù)據(jù)處理。接著Soul為每一個子節(jié)點添加添加訂閱者,訂閱節(jié)點的數(shù)據(jù)變化。
image.png

我們觀察每個ZkDataListener 主要監(jiān)聽Datachange 事件和DataDelete事件。
image.png

這里還是還是調(diào)用 cacheSelectorData 方法 ,主要還是調(diào)用 CommonPluginDataSubscriber 的 onSelectorSubscribe 方法,這里的 DataCache 就是緩存了所有數(shù)據(jù)的工廠,我們只需要更新這個工廠的數(shù)據(jù)。接著調(diào)用該插件的 handlerSelector 方法,這是個Defaut 方法留給各個插件實現(xiàn),各個插件也可以選擇不實現(xiàn)。


image.png

image.png

這樣我們整個Zookeeper的更新流程就走完了,是不是很簡單。

1.5.3 總結(jié)

今天我們又掌握了Spring 的一些常用技巧如 @Import + @ConfigurationProperties + @EnableConfigurationProperties 這個三個注解組成的元數(shù)據(jù)加載方法,還有CommonLineRunner 通用的啟動后處理機制。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容