Soul-源码阅读15-Nacos同步数据分析3-admin端

本次分析在0125号萧大佬修复了:当Nacos数据是空的时候,soul-admin不会初始化同步数据到nacos,问题之后。

soul-admin 如何同步网关数据
  • 这块的数据更新其实类似zookeeper、websocket。

  • soul-admin数据初始化全量更新,在DataSyncConfiguration类的内部类监听NacosListener

    @Configuration
    public class DataSyncConfiguration {
    //.......
        @Configuration
        @ConditionalOnProperty(prefix = "soul.sync.nacos", name = "url")
        @Import(NacosConfiguration.class)
        static class NacosListener {
            @Bean
            @ConditionalOnMissingBean(NacosDataChangedListener.class)
            public DataChangedListener nacosDataChangedListener(final ConfigService configService) {
                return new NacosDataChangedListener(configService);
            }
            @Bean
            @ConditionalOnMissingBean(NacosDataInit.class)
            public NacosDataInit nacosDataInit(final ConfigService configService, final SyncDataService syncDataService) {
                return new NacosDataInit(configService, syncDataService);
            }
        }
    
  • ZookeeperDataInit的 run 方法,判断其数据节点是否存在,如果不存在,则调用同步数据SyncDataServiceImpl#syncAll 方法

    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);
        }
    }
    
  • 发送了五种类型数据事件,看这里ApplicationEventPublisher发布了一个订阅DataChangedEvent,这边有一套spring的事件通知机制:这个DataChangedEvent继承了ApplicationEventDataChangedEventDispatcher(事件分发器)实现了ApplicationListener,DataChangedEventDispatcher初始化完成后会执行 afterPropertiesSet(),在容器中获取所有类型是DataChangedListener.class的bean, 就找到了DataChangedListener接口,再找到实现类NacosDataChangedListener,下面大概说明。

@Override
public boolean syncAll(final DataEventTypeEnum type) {
    appAuthService.syncData();
    List<PluginData> pluginDataList = pluginService.listAll();
    eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.PLUGIN, type, pluginDataList));
    List<SelectorData> selectorDataList = selectorService.listAll();
    eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.SELECTOR, type, selectorDataList));
    List<RuleData> ruleDataList = ruleService.listAll();
    eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.RULE, type, ruleDataList));
    metaDataService.syncData();
    return true;
}
@Override
public void afterPropertiesSet() {
    Collection<DataChangedListener> listenerBeans = applicationContext.getBeansOfType(DataChangedListener.class).values();
    this.listeners = Collections.unmodifiableList(new ArrayList<>(listenerBeans));
}
  • DataChangedEventDispatcher 监听到变更事件后,会执行 onApplicationEvent,遍历所有的监听类对监听事件进行处理,这里是NacosDataChangedListener

    public void onApplicationEvent(final DataChangedEvent event) {
        for (DataChangedListener listener : listeners) {
            switch (event.getGroupKey()) {
                // ......
                case META_DATA:
                    listener.onMetaDataChanged((List<MetaData>) event.getSource(), event.getEventType());
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + event.getGroupKey());
            }
        }
    }
    
  • NacosDataChangedListener 会执行 onSelectorChanged,updateSelectorMap先将网关数据同步至内存SELECTOR_MAP,在通过publishConfig同步至nacos。

    public void onSelectorChanged(final List<SelectorData> changed, final DataEventTypeEnum eventType) {
        updateSelectorMap(getConfig(NacosPathConstants.SELECTOR_DATA_ID));
        switch (eventType) {
            // ......
            default:
                changed.forEach(selector -> {
                    List<SelectorData> ls = SELECTOR_MAP
                            .getOrDefault(selector.getPluginName(), new ArrayList<>())
                            .stream()
                            .filter(s -> !s.getId().equals(selector.getId()))
                            .sorted(SELECTOR_DATA_COMPARATOR)
                            .collect(Collectors.toList());
                    ls.add(selector);
                    SELECTOR_MAP.put(selector.getPluginName(), ls);
                });
                break;
        }
        publishConfig(NacosPathConstants.SELECTOR_DATA_ID, SELECTOR_MAP);
    }
    

总结

1、soul-admin 更新网关数据,发布一个DataChangedEvent事件,eventPublisher.publishEvent(new DataChangedEvent())。
2、DataChangedEventDispatcher --> onApplicationEvent()方法监听事件,初始化完成后会执行 afterPropertiesSet(),监听接口是DataChangedListener 实现类是 NacosDataChangedListener
3、NacosDataChangedListener --> onSelectorChanged()处理事件。
4、同步至内存 updateSelectorMap(getConfig(NacosPathConstants.SELECTOR_DATA_ID))。
5、publishConfig(NacosPathConstants.SELECTOR_DATA_ID, SELECTOR_MAP)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值