本文主要接者上文说的 admin 的流程,讨论一下 Bootstrap 端的流程和 Zookeeper 数据同步方式的时序图。
Bootstrap 端
启动 bootStrap 时,命令行的日志显示 zkClient 启动并完成了数据同步。
2021-01-26 11:34:58.346 INFO 34694 --- [ main] s.b.s.d.z.ZookeeperSyncDataConfiguration : you use zookeeper sync soul data.......
2021-01-26 11:34:58.354 INFO 34694 --- [-localhost:2181] org.I0Itec.zkclient.ZkEventThread : Starting ZkClient event thread.
...
2021-01-26 11:34:58.445 INFO 34694 --- [ain-EventThread] org.I0Itec.zkclient.ZkClient : zookeeper state changed (SyncConnected)
启动时
soul 封装了自己的 boot,将 ZookeeperSyncDataConfiguration
纳入自动配置中。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.dromara.soul.spring.boot.sync.data.zookeeper.ZookeeperSyncDataConfiguration
ZookeeperSyncDataConfiguration
中 SyncDataService
, ZkClient
注册了 Bean,而 ·SyncDataService
是个接口类,实际上是 ZookeeperSyncDataService
, 该实现的构造函数中含有 watcherData, watchAppAuth, watchMetaData 的方法, 这个三个方法都是都是直接或者间接更新本地的缓存,并调用 zkClient.subscribeDataChanges 开启监听 Zookeeper 的数据变更。
大致流程图如下:
这个流程重在 ZookeeperSyncDataService 中。
更新数据时
由于启动时, zkClient.subscribeDataChanges 也开启了数据变化监听, 以更改 rule 为例, 在 subscribeRuleDataChanges 方法中得到看出:
private void subscribeRuleDataChanges(final String path) {
zkClient.subscribeDataChanges(path, new IZkDataListener() {
@Override
public void handleDataChange(final String dataPath, final Object data) {
cacheRuleData((RuleData) data);
}
...
});
}
zkClient 订阅到了 Zookeeper 的数据变更,最终在 CommonPluginDataSubscriber#subscribeDataHandler 的方法中,进行配置的更新。大致如下:
时序图
经过 admin 端和 bootstrap 端的数据流转,再此总结一下总的时序图。
总结
- Zookeeper 数据同步的大体思想和之前的 Nacos 很相近,都是先写入注册中心,然后 bootstrap 端从注册中心拿数据。
- 利用 MapStruct 生成对应的实现类,可以在日常开发中使用。Mapping Frameworks 的对比
- Zookeeper 的 watch 机制还需要进一步的深入。
- 时序图和 uml 的表达方式还得再加强。