【高性能网关soul学习】9. soul 数据同步之 Nacos

【高性能网关soul学习】9. soul 数据同步之 Nacos

本文目标:介绍 soul-admin 与 soul-web 之间通过 Nacos 进行同步的细节


配置 nacos 进行数据同步

nacos文档

  1. 启动nacos之后,首先需要手动配置一个namespace
    • namespace 的 id 设置为 1c10d748-af86-43b9-8265-75f487d20c6c
    • 命名为 soul
  2. soul-bootstrap 网关服务引入依赖 和进行配置
<!--soul data sync start use nacos-->
<dependency>
   <groupId>org.dromara</groupId>
   <artifactId>soul-spring-boot-starter-sync-data-nacos</artifactId>
   <version>${project.version}</version>
</dependency>
soul:
  sync:
    nacos:
      url: localhost:8848
      namespace: 1c10d748-af86-43b9-8265-75f487d20c6c
      acm: 
        enabled: false
        endpoint: acm.aliyun.com
        namespace:
        accessKey:
        secretKey:
#url: 配置成你的nacos地址,集群环境请使用(,)分隔。
# 其他参数配置,请参考naocs官网。
  1. soul-admin 配置
soul:
  sync:
    websocket:
      enabled: false
    nacos:
      url: localhost:8848
      namespace: 1c10d748-af86-43b9-8265-75f487d20c6c
      acm:
        enabled: false
        endpoint: acm.aliyun.com
        namespace:
        accessKey:
        secretKey:

依次启动 soul-admin、测试的server、soul-bootstrap

  • 服务启动完毕之后,nacos控制台数据应该数据配置上来了

nacos控制台数据配置

  • 目前版本有些问题(2021-01-24 2.3.0版本),soul-admin 启动时,并不会在启动时把所有全量数据配置上来。
  • 因此 soul-bootstrap 可能会启动失败,debug 了下,发现如果配置为 nacos 方式,如果nacos上未配置五种data 就会导致空指针报错启动失败(暂时是手动修改捕获到异常类型为Exception,使其不影响跑例子)
    • soul-bootstrap 启动时 start 方法中会加载 “soul.plugin.json”;“soul.selector.json”; “soul.rule.json”;“soul.auth.json”;“soul.meta.json”; 这五种配置项
public void start() {
    watcherData(PLUGIN_DATA_ID, this::updatePluginMap);
    watcherData(SELECTOR_DATA_ID, this::updateSelectorMap);
    watcherData(RULE_DATA_ID, this::updateRuleMap);
    watcherData(META_DATA_ID, this::updateMetaDataMap);
    watcherData(AUTH_DATA_ID, this::updateAuthMap);
}
soul-admin 端的数据修改同步到 nacos
  • 大致逻辑和之前几种方式类似 NacosDataChangedListener 在触发 DataChangedEvent 时

    • update:修改自己内存中的数据,然后推送数据变动到nacos
  • public class NacosDataChangedListener implements DataChangedListener {
    @Override
        public void onSelectorChanged(final List<SelectorData> changed, final DataEventTypeEnum eventType) {
            updateSelectorMap(getConfig(SELECTOR_DATA_ID));
            switch (eventType) {
                case DELETE:
                    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());
                        SELECTOR_MAP.put(selector.getPluginName(), ls);
                    });
                    break;
                case REFRESH:
                case MYSELF:
                    ...;
                    break;
                default:
                    ...;
                    break;
            }
            publishConfig(SELECTOR_DATA_ID, SELECTOR_MAP);
        }
      
      
        @SneakyThrows
        private void publishConfig(final String dataId, final Object data) {
          // 推送数据变动到 nacos 
            configService.publishConfig(dataId, GROUP, GsonUtils.getInstance().toJson(data));
        }
    
    }
    
soul-bootstrap 端的nacos 数据同步流程
  • 启动时调用start方法,start方法中又对五种配置项调用 watcherData 方法,watcherData 大致逻辑
    • 创建一个 listener 监听数据的后续变化,通过 getConfigAndSignListener 进行注册listener
    • 然后在 watcherData 中直接触发一次加载
// NacosCacheHandler.java
watcherData(SELECTOR_DATA_ID, this::updateSelectorMap);

protected void watcherData(final String dataId, final OnChange oc) {
  // 创建一个 listener 监听后续的变化图
    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.getOrDefault(dataId, new ArrayList<>()).add(listener);
}

@SneakyThrows
private String getConfigAndSignListener(final String dataId, final Listener listener) {
    return configService.getConfigAndSignListener(dataId, GROUP, 6000, listener);
}

protected void updateSelectorMap(final String configInfo) {
    try {
      // nacos 获取到的数据 进行序列化
        List<SelectorData> selectorDataList = GsonUtils.getInstance().toObjectMapList(configInfo, SelectorData.class).values().stream().flatMap(Collection::stream).collect(Collectors.toList());
      // 回调 dataSubscriber
        selectorDataList.forEach(selectorData -> Optional.ofNullable(pluginDataSubscriber).ifPresent(subscriber -> {
            subscriber.unSelectorSubscribe(selectorData);
            subscriber.onSelectorSubscribe(selectorData);
        }));
    } catch (JsonParseException e) {
        log.error("sync selector data have error:", e);
    }
}

总结:

  1. 介绍了 soul 关于 nacos 进行数据同步的相关配置
    1. 整体的数据同步机制还是比较简单的,和zookeeper类似
    2. 为什么会导致 soul-admin 不能同步全量数据到 nacos 还需要进一步研究
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值