写点什么

Soul 源码阅读 04|Zookeeper 同步数据分析

用户头像
哼干嘛
关注
发布于: 2021 年 01 月 26 日

一、使用 Zookeeper 进行数据同步

  • 修改 soul-admin 和网关的配置,同步方式都设置成 zookeeper



二、soul-admin 更新 zookeeper 节点

  1. soul-admin 在启动的时候,如果 zookeeper 中之前不包含 soul 的节点信息,会将数据全量写入 zookeeper 。

// org.dromara.soul.admin.listener.zookeeper.ZookeeperDataInit@Overridepublic void run(final String... args) {  String pluginPath = ZkPathConstants.PLUGIN_PARENT;  String authPath = ZkPathConstants.APP_AUTH_PARENT;  String metaDataPath = ZkPathConstants.META_DATA;  if (!zkClient.exists(pluginPath) && !zkClient.exists(authPath) && !zkClient.exists(metaDataPath)) {    syncDataService.syncAll(DataEventTypeEnum.REFRESH);  }}
复制代码


# 使用./zkCli.sh -server 127.0.0.1:2181 连接到zookeeper服务器查看一下节点信息# 初始状态,此时没有 soul 节点[zk: 127.0.0.1:2181(CONNECTED) 0] ls /[dubbo, sofa-rpc, zookeeper]# 运行 soul-admin 后,再次查看节点信息,发现soul节点已被添加,数据初始化设置成功。[zk: 127.0.0.1:2181(CONNECTED) 1] ls /[dubbo, sofa-rpc, soul, zookeeper][zk: 127.0.0.1:2181(CONNECTED) 2] ls /soul[plugin, rule, selector] #由于没有设置用户授权信息和元数据信息,所以此时没有auth和metadata节点
复制代码


  1. 后续数据发生变更时,会通过 ApplicationEventPublisher 发布变更事件,ZookeeperDataChangedListener 监听到事件后,更新 zookeeper 的节点。

例:

// org.dromara.soul.admin.listener.zookeeper.ZookeeperDataChangedListener@Overridepublic void onAppAuthChanged(final List<AppAuthData> changed, final DataEventTypeEnum eventType) {  for (AppAuthData data : changed) {    String appAuthPath = ZkPathConstants.buildAppAuthPath(data.getAppKey());    // delete    if (eventType == DataEventTypeEnum.DELETE) {      deleteZkPath(appAuthPath);      continue;    }    // create or update    insertZkNode(appAuthPath, data);  }}
复制代码


# 增加授权信息[zk: 127.0.0.1:2181(CONNECTED) 3] ls /soul[auth, plugin, rule, selector][zk: 127.0.0.1:2181(CONNECTED) 5] ls /soul/auth[0D6197207DCB4EC6BF593A36C3728189]
复制代码

三、网关接收处理数据变动

网关在建立连接时,就通过 zookeeper 的 watch 机制,开启了对配置信息节点的监听

// org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService#ZookeeperSyncDataServicepublic ZookeeperSyncDataService(final ZkClient zkClient, final PluginDataSubscriber pluginDataSubscriber,                                final List<MetaDataSubscriber> metaDataSubscribers, final List<AuthDataSubscriber> authDataSubscribers) {  this.zkClient = zkClient;  this.pluginDataSubscriber = pluginDataSubscriber;  this.metaDataSubscribers = metaDataSubscribers;  this.authDataSubscribers = authDataSubscribers;  watcherData(); //包含对插件&选择器&规则的监听  watchAppAuth();  watchMetaData();}
复制代码

当监听的节点发生变动时,会通知到对应的订阅器 AuthDataSubscriberMetaDataSubscriberPluginDataSubscriber ,做数据处理。

例:

// 监听插件节点变动private void watcherPlugin(final String pluginName) {  String pluginPath = ZkPathConstants.buildPluginPath(pluginName);  if (!zkClient.exists(pluginPath)) {    zkClient.createPersistent(pluginPath, true);  }  cachePluginData(zkClient.readData(pluginPath));  subscribePluginDataChanges(pluginPath, pluginName);}
复制代码


//监听到节点变动时,通知PluginDataSubscriberprivate void subscribePluginDataChanges(final String pluginPath, final String pluginName) {  zkClient.subscribeDataChanges(pluginPath, new IZkDataListener() {
@Override public void handleDataChange(final String dataPath, final Object data) { Optional.ofNullable(data) .ifPresent(d -> Optional.ofNullable(pluginDataSubscriber).ifPresent(e -> e.onSubscribe((PluginData) d))); }
@Override public void handleDataDeleted(final String dataPath) { final PluginData data = new PluginData(); data.setName(pluginName); Optional.ofNullable(pluginDataSubscriber).ifPresent(e -> e.unSubscribe(data)); } });}
复制代码


发布于: 2021 年 01 月 26 日阅读数: 28
用户头像

哼干嘛

关注

早日自由! 2018.09.30 加入

本职工作是后端开发,偶尔也写写前端和小程序

评论

发布
暂无评论
Soul 源码阅读 04|Zookeeper 同步数据分析