soul网关-18-数据同步机制之nacos

关于soul网关的数据同步机制,已经从源码里面大致了解了websocket数据同步http长轮询数据同步zookeeper数据同步,今天来看一下soul网关是怎么使用nacos进行数据同步的。

先来了解一下nacos,根据nacos官方文档的介绍,可以知道:

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

那么可以猜测soul网关使用nacos进行数据同步的话,其原理和使用zookeeper是差不多的。数据同步的步骤可以理解成以下几个:

  • 业务方将API注册到soul-admin
  • soul-admin将配置信息上传到nacos(或zookeeper)
  • soul-bootstrap启动的时候,会拉取nacos(或zookeeper)上的信息,并且对数据的变动进行监听
  • 管理员在soul-admin修改配置、或者有新的业务方注册API到soul-admin的时候,soul-admin将变动的数据上传到nacos(或zookeeper)
  • soul-bootstrap监听到数据更新之后,更新自己保存在内存中的配置信息

nacos安装

我们先来安装一下nacos,以便后面进行调试。nacos可以在官方github上下载

目前为止,nacos最新的是2.0.0-alpha.2。我们可以直接下载压缩文件。

解压之后,会看到目录里面有如下文件:

在这里插入图片描述

使用命令sh bin/startup.sh -m standalone就可以以单机模式启动nacos,它默认运行在8848端口。

我们在浏览器里面输入http://127.0.0.1:8848/nacos,看到登录入口,输入nacos/nacos就可以进入管理界面

在这里插入图片描述

soul网关使用nacos数据同步

nacos安装之后,我们可以将soul-admin管理后台、示例项目、网关运行起来。

soul-admin管理后台运行之前,确保application.yml配置文件里面,设置的数据同步方式是nacos,然后让soul-admin跑起来

soul:
	sync:
      nacos:
        url: localhost:8848
        namespace: 1c10d748-af86-43b9-8265-75f487d20c6c
        acm:
          enabled: false
          endpoint: acm.aliyun.com
          namespace:
          accessKey:
          secretKey:

然后运行soul-examples-http示例项目,就可以在soul-admin的divide插件里面看到示例项目的API已经映射到selector和rule里面了。

在这里插入图片描述

按照上面我们分析的数据同步方式,此时soul-admin已经把配置都上传到了nacos了,我们去nacos的管理界面看一下。

…………在配置管理->配置列表里面啥也没看到,我还以为是我的nacos地址配错了,或者是什么原因导致soul-admin往nacos上传数据失败。后来在nacos管理后台的命名空间里看了一下,发现只有一个public(保留空间),而我们用的空间名是1c10d748-af86-43b9-8265-75f487d20c6c,在命名空间的界面上没有。

于是,加上这个命名空间,如下图所示

在这里插入图片描述

然后在配置管理->配置列表里面,切换到刚刚加上的命名空间,就可以看到数据了。

在这里插入图片描述

我们看一下soul.plugin.json这个配置的详情,如下图所示,和我们想的一样,是各个插件的PluginData对象的json形式

在这里插入图片描述

再来看一下soul.selector.json这个配置的详情,如下图所示

在这里插入图片描述

然后我们运行soul-boostrap试一下能不能正常通过网关进行api请求,在运行soul-bootstrap之前,确保pom.xml里面有以下依赖:

        <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>soul-spring-boot-starter-sync-data-nacos</artifactId>
            <version>${project.version}</version>
        </dependency>

确保soul-bootstrap的application.yml配置文件里面配置的数据同步方式也是nacos

soul:
    sync:
        nacos:
          url: localhost:8848
          namespace: 1c10d748-af86-43b9-8265-75f487d20c6c
          acm:
            enabled: false
            endpoint: acm.aliyun.com
            namespace:
            accessKey:
            secretKey:

在浏览器里面输入一个url测试一下,可以通过网关正常访问业务方的api

在这里插入图片描述

在我们分析soul网关关于nacos数据同步的原理之前,我们先去nacos官网看下它提供的一些API

  • 获取配置的API getConfig
  • 发布配置的API publishConfig
  • 取消监听的API removeListener
  • 还有一个API getConfigAndSignListener在官方文档里没找到,不过在网上搜了一下,这个API的意思是获取配置的时候注册一个监听器

在这里插入图片描述

soul-admin是如何使用nacos来进行数据同步的

上面已经粗略的了解了一下nacos提供的几个重要的API,下面从源码里面来看下soul-admin是如何使用nacos来进行数据同步的。

有了之前学习websocket数据同步http长轮询数据同步zookeeper数据同步的经验,我们知道在DataSyncConfiguration这个声明了@Configuration注解的类里面,检测到如果配置文件里面有soul.sync.nacos,就会像spring容器注入NacosDataChangedListenerNacosDataInit两个bean。

在这里插入图片描述

来看一下NacosDataInit,它与之前分析过的ZookeeperDataInit类似,主要的逻辑就是:

  • 判断注册中心的配置不存在的时候,就将配置上传到注册中心去

我们也知道了DataChangedEventDispatcher这个数据变动事件分发器,它实现了ApplicationListener接口,当监听到DataChangedEvent这个事件的时候,就会调用各种XXXDataChangedListeneronxxChanged方法。

我们来看下NacosDataChangedListener里面的一些属性,可以看到是使用了ConcurrentMap来在内存中存储PluginData、SelectorData、RuleData、AppAuthData、MetaData。

看到NacosDataChangedListener里面一些方法,可以看到熟悉的onAppAuthChangedonPluginChangedonSelectorChanged……

onSelectorChanged为例,看一下里面的逻辑,以UPDATE为例,具体的逻辑是:

  • 从nacos拉取selector配置,并缓存到SELECTOR_MAP中
  • 根据改动的selector,更新SELECTOR_MAP内存中缓存的selector配置信息
  • 将最新的selector配置信息上传到nacos

在这里插入图片描述

soul-bootstrap是如何使用nacos来进行数据同步的

看完了soul-admin的nacos数据同步部分,下面来看下soul-bootstrap的nacos数据同步部分。

我们可以直接找到soul-sync-data-nacos模块里面找到NacosSyncDataServices,它的构造函数里面调用了start()方法,在start()方法里面拉取了nacos配置并且注册了listener。

watcherData(PLUGIN_DATA_ID, this::updatePluginMap);这句话的意思就是从nacos拉取plugin相关配置,并且注册监听,当监听到变动的时候,就调用本地的updatePluginMap方法。可能这种形式比较难理解,但是我们可以从最基础的来变形到这一种。

我们看下watcherData方法接收两个参数,第二个参数是一个Interface

    protected void watcherData(final String dataId, final OnChange oc)

我们一开始可以这样写:

		watcherData(PLUGIN_DATA_ID, new OnChange() {
            @Override
            public void change(String changeData) {
                updatePluginMap(changeData);
            }
        });

然后IDEA编辑器会提示你可以简化成lambda表达式的形式,然后就简化成这样:

        watcherData(PLUGIN_DATA_ID, changeData -> updatePluginMap(changeData));

然后IDEA编辑器还提示可以进行简化,最后就简化成这样:

        watcherData(PLUGIN_DATA_ID, this::updatePluginMap);

其实这个watcherData方法的主要作用就是:

  • 从nacos拉取配置的时候顺便注册listener
  • 将listener使用一个map存在内存中。(这些listener会在NacosSyncDataService结束的时候取消监听)
    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);
    }

我们来看下updatePluginMap方法,它会在监听到nacos的plugin配置变动的时候被调用。从updatePluginMap里面我们可以看到熟悉的subscriber.unSubscribe()subscriber.onSubscribe()方法,它最终会去更新内存中缓存的数据。

   protected void updatePluginMap(final String configInfo) {
        try {
            List<PluginData> pluginDataList = new ArrayList<>(GsonUtils.getInstance().toObjectMap(configInfo, PluginData.class).values());
            pluginDataList.forEach(pluginData -> Optional.ofNullable(pluginDataSubscriber).ifPresent(subscriber -> {
                subscriber.unSubscribe(pluginData);
                subscriber.onSubscribe(pluginData);
            }));
        } catch (JsonParseException e) {
            log.error("sync plugin data have error:", e);
        }
    }

至此,我们已经把soul网关如何使用nacos进行数据同步的大致流程梳理清楚了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值