【高性能网关soul学习】9. soul 数据同步之 Nacos
本文目标:介绍 soul-admin 与 soul-web 之间通过 Nacos 进行同步的细节
配置 nacos 进行数据同步
- 启动nacos之后,首先需要手动配置一个namespace
- namespace 的 id 设置为 1c10d748-af86-43b9-8265-75f487d20c6c
- 命名为 soul
- 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官网。
- 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控制台数据应该数据配置上来了
- 目前版本有些问题(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);
}
}
总结:
- 介绍了 soul 关于 nacos 进行数据同步的相关配置
- 整体的数据同步机制还是比较简单的,和zookeeper类似
- 为什么会导致 soul-admin 不能同步全量数据到 nacos 还需要进一步研究