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

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

這里會根據(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 。

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

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

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

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

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

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

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

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

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

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


這樣我們整個Zookeeper的更新流程就走完了,是不是很簡單。
1.5.3 總結(jié)
今天我們又掌握了Spring 的一些常用技巧如 @Import + @ConfigurationProperties + @EnableConfigurationProperties 這個三個注解組成的元數(shù)據(jù)加載方法,還有CommonLineRunner 通用的啟動后處理機制。