Soul-源码阅读12-Zookeeper同步数据分析2

继上节分析2

  • soul的各种插件启动基本流程是通过自定义starter启动,然后内部做一系列的依赖注入。
    在这里插入图片描述

  • 上1节我们知道soul-bootstrap 引入上面这个starter,里面的启动配置类 ZookeeperSyncDataConfiguration,创建了同步数据的syncDataService类,再往spring容器注册了zkClient。其实这里面还有个知识点:ObjectProvider Bean依赖查找注入,

    然后实例化的zkclient有url、session超时时间和连接超时时间。

    public ZkClient zkClient(final ZookeeperConfig zookeeperConfig) {
        return new ZkClient(zookeeperConfig.getUrl(), zookeeperConfig.getSessionTimeout(), zookeeperConfig.getConnectionTimeout());
    }
    
  • 上面这三个参数,就是上文分析中的 boot-strap的application-local.yml配置的。

    zookeeper:
         url: localhost:2181
         sessionTimeout: 5000
         connectionTimeout: 2000
    
  • ZookeeperSyncDataService初始化一个缓存管理器,全量给需要关注的节点增加watch机制,每次触发数据变动,就先watch 然后在处理事件。

    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();
    }
    
  • 将需要关注的节点绑定watcher事件触发之后,处理的方法subscribePluginDataChanges

    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);
    }
    
  • 监听到数据变动后处理

    private 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));
            }
        });
    }
    
  • soul-admin数据初始化全量更新,在DataSyncConfiguration类的内部类zk监听ZookeeperListener

    @Bean
    @ConditionalOnMissingBean(ZookeeperDataInit.class)
    public ZookeeperDataInit zookeeperDataInit(final ZkClient zkClient, final SyncDataService syncDataService) {
        return new ZookeeperDataInit(zkClient, syncDataService);
    }
    
    public class ZookeeperDataInit implements CommandLineRunner {
    
    ......
        @Override
        public 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);
            }
        }
    }
    
  • SyncDataServiceImpl#syncAll 方法, 发送了五种类型数据事件,看这里ApplicationEventPublisher发布了一个订阅DataChangedEvent,这边有一套spring的事件通知机制:这个DataChangedEvent继承了ApplicationEvent,ApplicationEvent (记录事件源和数据)和 ApplicationListener(事件监听者)配套使用的,DataChangedEventDispatcher(事件分发器)实现了ApplicationListener,就找到了DataChangedListener接口,再找到实现类ZookeeperDataChangedListener

    @Override
    public boolean syncAll(final DataEventTypeEnum type) {
        。。。。。。
        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.RULE, type, ruleDataList));
        metaDataService.syncData();
        return true;
    }
    

小结:

后台通过 DataSyncConfiguration 配置类去注入 zk监听器为 Spring Bean (内部类ZookeeperListener),admin 主要通过ApplicationEvent 发送数据变动事件,然后通过具体通信插件将数据告知网关端,网关通过订阅模式将信息告知对应关心数据的通信协议插件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值