第三代半导体 Filecoin WorldCloud Transformer ruby performance qt sockets model architecture vue遍历 mysql当前时间减一天 node卸载命令 linux关闭mysql 安卓程序源代码 div字体加粗 dwf文件怎么转成dwg mysql分区表优劣分析 mysql时间戳转时间 python的range python定义一个变量 python调用自定义函数 python基础代码 java连接mysql java语言学习 javasocket通信 java的环境配置 java将数据写入文件 java获取数据类型 java遍历list集合 java怎么学 java学习流程 java字符 行业软件下载 linux操作系统原理 corelpainter 乱码查看器 超级煎蛋卷 倒计时计时器 html特殊字符
当前位置: 首页 > 学习教程  > 编程语言

Soul-源码阅读14-Nacos同步数据分析2

2021/1/28 23:58:20 文章标签:

问题回顾解决 继续分析昨天boot-strap启动报错NPE的问题,提示: org.springframework.beans.factory.BeanCreationException: Error creating bean with name nacosSyncDataService defined in class path resource [org/dromara/soul/springboot/start…

问题回顾解决

继续分析昨天boot-strap启动报错NPE的问题,提示:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nacosSyncDataService' defined in class path resource [org/dromara/soul/springboot/starter/sync/data/nacos/NacosSyncDataConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dromara.soul.sync.data.api.SyncDataService]: Factory method 'nacosSyncDataService' threw exception; nested exception is com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException: RPC-010010015: 构造客户端代理出错! 

原因是:soul-bootstrap 启动的时候会去,nacos获取网关数据,通过debugger,拿到的是空数据,使用nacos同步数据的时候,如果网关只代理http服务(无元数据),soul-bootstrap是启动不起来的。

  • 去启动一下sofa服务。然后在soul-admin同步一下元数据。
  • soul-admin 在系统管理-元数据管理, 点击同步数据按钮,将元数据会同步到nacos。
  • 再次启动boot-strap,就提示成功啦。
2021-01-28 22:56:36.092  INFO 14652 --- [           main] d.s.s.s.s.d.n.NacosSyncDataConfiguration : you use nacos sync soul data.......
2021-01-28 22:56:37.318  INFO 14652 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2021-01-28 22:56:39.379  INFO 14652 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 9195
2021-01-28 22:56:39.394  INFO 14652 --- [           main] o.d.s.b.SoulBootstrapApplication         : Started SoulBootstrapApplication in 10.686 seconds (JVM running for 16.254)

在这里插入图片描述

小结:soul-bootstrap 启动不起来报空指针异常,首先soul-admin启动后不会主动向nacos同步网关数据,需要手动同步,这个问题困扰了挺长时间,最后是看了其他同学的分享,才恍然大悟。

源码分析

  • 数据初始化更新的时候 NacosCacheHandler,通过调用 watcherData 方法,使用Nacos提供的 Listener 来注册当Nacos发布配置时候,可以监听到事件。

    public class NacosCacheHandler {
    。。。。。。
        protected void watcherData(final String dataId, final OnChange oc) {
            Listener listener = new Listener() {
                @Override
                public void receiveConfigInfo(final String configInfo) {
                    oc.change(configInfo);
                }
    
                @Override
                public Executor getExecutor() {
                    return null;
                }
            };
            oc.change(getConfigAndSignListener(dataId, listener));
            LISTENERS.computeIfAbsent(dataId, key -> new ArrayList<>()).add(listener);
        }
    
  • soul-admin的Nacos配置类 NacosConfiguration#nacosConfigService 初始化bean时通过 NacosFactory 创建配置服务。 DataChangedEventDispatcher 负责调用具体的监听实现类对 DataChangedEvent事件进行处理,实现类NacosDataChangedListener 监听器会监听配置的变化,NacosDataChangedListener 会执行 onRuleChanged,updateRuleMap 先将网关数据同步至内存,在通过publishConfig同步至nacos。

    public ConfigService nacosConfigService(final NacosProperties nacosProp) throws Exception {
        Properties properties = new Properties();
        if (nacosProp.getAcm() != null && nacosProp.getAcm().isEnabled()) {
            // Use aliyun ACM service
            properties.put(PropertyKeyConst.ENDPOINT, nacosProp.getAcm().getEndpoint());
            properties.put(PropertyKeyConst.NAMESPACE, nacosProp.getAcm().getNamespace());
            // Use subaccount ACM administrative authority
            properties.put(PropertyKeyConst.ACCESS_KEY, nacosProp.getAcm().getAccessKey());
            properties.put(PropertyKeyConst.SECRET_KEY, nacosProp.getAcm().getSecretKey());
        } else {
            properties.put(PropertyKeyConst.SERVER_ADDR, nacosProp.getUrl());
            properties.put(PropertyKeyConst.NAMESPACE, nacosProp.getNamespace());
        }
        return NacosFactory.createConfigService(properties);
    }
    
    public void onSelectorChanged(final List<SelectorData> changed, final DataEventTypeEnum eventType) {
        updateSelectorMap(getConfig(NacosPathConstants.SELECTOR_DATA_ID));
        .。。。
        publishConfig(NacosPathConstants.SELECTOR_DATA_ID, SELECTOR_MAP);
    }
    
  • soul-bootstrap 添加了nacos依赖soul-spring-boot-starter-sync-data-nacos ,启动时自动注入类 NacosSyncDataConfiguration 在初始化bean是创建了 NacosSyncDataService 用于监听配置数据的变化并进行同步。

    public SyncDataService nacosSyncDataService(final ObjectProvider<ConfigService> configService, final ObjectProvider<PluginDataSubscriber> pluginSubscriber,
                                           final ObjectProvider<List<MetaDataSubscriber>> metaSubscribers, final ObjectProvider<List<AuthDataSubscriber>> authSubscribers) {
        log.info("you use nacos sync soul data.......");
        return new NacosSyncDataService(configService.getIfAvailable(), pluginSubscriber.getIfAvailable(),
                metaSubscribers.getIfAvailable(Collections::emptyList), authSubscribers.getIfAvailable(Collections::emptyList));
    }
    

总结:

数据同步原理目前看都是类似的,下一章计划深入分析 admin 和 bootstrap的整个过程,验证下。


本文链接: http://www.dtmao.cc/news_show_650337.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?