数据同步的几种方式也看的差不多了,还剩下 http 长轮询,我准备先搁置下,今天简单写个总结贴,明天再分析下 nacos 同步,接下来就重点看网关是如何使用调用链转发请求的了。

数据同步的处理是在每个 listener 里面,这些 listener 都实现了接口 DataChangedListener,然后在自己类内部,根据自己的同步机制,进行对应的处理。

当有数据变更时,中间有个 dispatcher 转发,寻找对应的 listener 去调用具体的方法即可。

这一块设计我觉得特别好,尤其是还在 DataSyncConfiguration 类里,根据 yml 文件的配置去加载对应的 listener 的 bean,以后哪怕再加一种同步机制,也不需要改很多代码,这一块的扩展性很强。

而在 soul-bootstrap 这块,也会去根据 yml 文件中数据同步的配置,去加载对应 starter 的配置类。每个 starter 的具体实现又是在 soul-sync-data-center 里。

无论用哪种同步方式,最终同步到内存的那块代码也分离出来了,选择器和规则的处理都在 CommonPluginDataSubscriber 类,就是这个类去同步了内存中的数据。

    private <T> void subscribeDataHandler(final T classData, final DataEventTypeEnum dataType) {
        Optional.ofNullable(classData).ifPresent(data -> {
            if (data instanceof PluginData) {
                //处理插件数据
                PluginData pluginData = (PluginData) data;
                if (dataType == DataEventTypeEnum.UPDATE) {
                    BaseDataCache.getInstance().cachePluginData(pluginData);
                    Optional.ofNullable(handlerMap.get(pluginData.getName())).ifPresent(handler -> handler.handlerPlugin(pluginData));
                } else if (dataType == DataEventTypeEnum.DELETE) {
                    BaseDataCache.getInstance().removePluginData(pluginData);
                    Optional.ofNullable(handlerMap.get(pluginData.getName())).ifPresent(handler -> handler.removePlugin(pluginData));
                }
            } else if (data instanceof SelectorData) {
                //处理选择器数据
                SelectorData selectorData = (SelectorData) data;
                if (dataType == DataEventTypeEnum.UPDATE) {
                    BaseDataCache.getInstance().cacheSelectData(selectorData);
                    Optional.ofNullable(handlerMap.get(selectorData.getPluginName())).ifPresent(handler -> handler.handlerSelector(selectorData));
                } else if (dataType == DataEventTypeEnum.DELETE) {
                    BaseDataCache.getInstance().removeSelectData(selectorData);
                    Optional.ofNullable(handlerMap.get(selectorData.getPluginName())).ifPresent(handler -> handler.removeSelector(selectorData));
                }
            } else if (data instanceof RuleData) {
                //处理规则数据
                RuleData ruleData = (RuleData) data;
                if (dataType == DataEventTypeEnum.UPDATE) {
                    BaseDataCache.getInstance().cacheRuleData(ruleData);
                    Optional.ofNullable(handlerMap.get(ruleData.getPluginName())).ifPresent(handler -> handler.handlerRule(ruleData));
                } else if (dataType == DataEventTypeEnum.DELETE) {
                    BaseDataCache.getInstance().removeRuleData(ruleData);
                    Optional.ofNullable(handlerMap.get(ruleData.getPluginName())).ifPresent(handler -> handler.removeRule(ruleData));
                }
            }
        });
    }

可以看到代码的设计很精巧,用了大量的 Optional.ofNullable 方法和 @ConditionalOnProperty 注解,这一方面减少了很多 if else,另一方面也让代码看起来更加优雅。