soul网关数据同步之zookeeper同步方式探究(2)——bootstrap端同步

在《soul网关数据同步之zookeeper同步方式探究(1)——admin端同步》一文中,我们分析了admin端元数据同步到zk服务端的大致原理,本文继续分析bootstrap端与zk的元数据同步原理(zk版本为3.5.9),bootstrap的yml配置修改如下:

soul :
    file:
      enabled: true
    corss:
      enabled: true
    dubbo :
      parameter: multi
    sync:
#      websocket :
#         urls: ws://localhost:9095/websocket
      zookeeper:
        url: localhost:2181
        sessionTimeout: 5000
        connectionTimeout: 2000

注:之前在启动bootstrap时,遇到了一些问题,记录下下面两篇文章中:
(1) soul网关学习之bootstrap启动报错(问题记录)
(2).soul网关学习之bootstrap启动报错-问题初步解决

分析过程

  1. 启动bootstrap,会看到如下一行日志:
INFO 14692 --- [           main] s.b.s.d.z.ZookeeperSyncDataConfiguration : you use zookeeper sync soul data.......
  1. ok,就从ZookeeperSyncDataConfiguration 类入手,该类内容如下:
public class ZookeeperSyncDataConfiguration {

    /**
     * Sync data service sync data service.
     *
     * @param zkClient          the zk client
     * @param pluginSubscriber the plugin subscriber
     * @param metaSubscribers   the meta subscribers
     * @param authSubscribers   the auth subscribers
     * @return the sync data service
     */
    @Bean
    public SyncDataService syncDataService(final ObjectProvider<ZkClient> zkClient, final ObjectProvider<PluginDataSubscriber> pluginSubscriber,
                                           final ObjectProvider<List<MetaDataSubscriber>> metaSubscribers, final ObjectProvider<List<AuthDataSubscriber>> authSubscribers) {
        log.info("you use zookeeper sync soul data.......");
        return new ZookeeperSyncDataService(zkClient.getIfAvailable(), pluginSubscriber.getIfAvailable(),
                metaSubscribers.getIfAvailable(Collections::emptyList), authSubscribers.getIfAvailable(Collections::emptyList));
    }

    /**
     * register zkClient in spring ioc.
     *
     * @param zookeeperConfig the zookeeper configuration
     * @return ZkClient {@linkplain ZkClient}
     */
    @Bean
    public ZkClient zkClient(final ZookeeperConfig zookeeperConfig) {
        return new ZkClient(zookeeperConfig.getUrl(), zookeeperConfig.getSessionTimeout(), zookeeperConfig.getConnectionTimeout());
    }

}

ZookeeperSyncDataConfiguration 是一个配置类,初始化了一个zk客户端和一个数据同步服务ZookeeperSyncDataService。

  1. 进入ZookeeperSyncDataService,其构造函数如下:
public 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();
    }

服务设置了zk客户端,以及设置了插件数据和元数据等相关处理的订阅者,最下面的三个watch函数我们对watchMetaData进行分析。
4. watchMetaData

private void watchMetaData() {
        final String metaDataPath = ZkPathConstants.META_DATA;
        //获取元数据结点的所有子节点
        List<String> childrenList = zkClientGetChildren(metaDataPath);
        if (CollectionUtils.isNotEmpty(childrenList)) {
            childrenList.forEach(children -> {
                String realPath = buildRealPath(metaDataPath, children);
                //将每个子节点进行缓存
                cacheMetaData(zkClient.readData(realPath));
                //给子节点设置监听处理函数
                subscribeMetaDataChanges(realPath);
            });
        }
        subscribeChildChanges(ConfigGroupEnum.APP_AUTH, metaDataPath, childrenList);
    }
  1. subscribeMetaDataChanges函数是给客户端注册监听处理函数,具体如下:
private void subscribeMetaDataChanges(final String realPath) {
        zkClient.subscribeDataChanges(realPath, new IZkDataListener() {
        //节点变化后的处理
            @Override
            public void handleDataChange(final String dataPath, final Object data) {
           		//更新缓存
                cacheMetaData((MetaData) data);
            }

			//结点删除后的处理
            @SneakyThrows
            @Override
            public void handleDataDeleted(final String dataPath) {
                final String realPath = dataPath.substring(ZkPathConstants.META_DATA.length() + 1);
                MetaData metaData = new MetaData();
                metaData.setPath(URLDecoder.decode(realPath, StandardCharsets.UTF_8.name()));
                //删除缓存
                unCacheMetaData(metaData);
            }
        });
    }

验证时,在特定位置打上断点,前端元数据管理界面修改元数据配置,即可验证上述逻辑。

问题

  1. 前端直接新增的元数据貌似不能直接同步到bootstrap?点击同步按钮也不行?
  2. 前端批量删除元数据,boostrap报如下错误(尚未进行分析):
2021-01-30 03:15:16.686 ERROR 14344 --- [-localhost:2181] org.I0Itec.zkclient.ZkEventThread        : Error handling event ZkEvent[Children of /soul/metaData changed sent to org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService$$Lambda$543/1932866809@2e2f246]

java.lang.ClassCastException: org.dromara.soul.common.dto.MetaData cannot be cast to org.dromara.soul.common.dto.AppAuthData
	at org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService.lambda$12(ZookeeperSyncDataService.java:193) ~[classes/:na]
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_60]
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374) ~[na:1.8.0_60]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_60]
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_60]
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[na:1.8.0_60]
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[na:1.8.0_60]
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_60]
	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) ~[na:1.8.0_60]
	at org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService.lambda$11(ZookeeperSyncDataService.java:195) ~[classes/:na]
	at org.I0Itec.zkclient.ZkClient$10.run(ZkClient.java:844) ~[zkclient-0.10.jar:na]
	at org.I0Itec.zkclient.ZkEventThread.run(ZkEventThread.java:72) ~[zkclient-0.10.jar:na]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值