当前位置: 代码迷 >> 综合 >> Soul 网关源码阅读之 zookeeper 方式进行数据同步
  详细解决方案

Soul 网关源码阅读之 zookeeper 方式进行数据同步

热度:43   发布时间:2023-12-15 21:33:50.0

本次文章我们来探讨 Soul 中使用 zookeeper 的数据同步方式。

安装 zookeeper

首先准备安装包:https://zookeeper.apache.org/releases.html,下载的结果是 apache-zookeeper-3.6.2-bin.tar.gz,解压。
打开 conf 目录,在其中创建 zoo.cfg 文件,官方提供了一个示例文件 zoo_sample.cfg,可以仿照书写。主要需要修改的地方就是
在这里插入图片描述
数据文件目录这一行,改成我们自己需要的就行。
接下来打开 bin 目录,运行 zkServer.cmd,出现下图所示输出即为启动成功:
在这里插入图片描述
我们可以运行 zkCli.cmd 进行测试:
在这里插入图片描述

配置 Soul 网关

首先在 soul-admin 模块的 yml 文件中添加如下配置:

soul:sync:zookeeper:url: localhost:2181sessionTimeout: 5000connectionTimeout: 2000

紧接着在 soul-bootstrap 模块的 pom 文件中添加:

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

并在其 yml 文件中添加:

soul :sync:zookeeper:url: localhost:2181sessionTimeout: 5000connectionTimeout: 2000

org.dromara.soul.admin.listener.zookeeper.ZookeeperDataChangedListener

有了上篇文章的基础,这次我们直接看 DataChangedListener 接口的 zookeeper 实现即可。
仍然使用选择器规则修改作为示例:

	public void onRuleChanged(final List<RuleData> changed, final DataEventTypeEnum eventType) {
    if (eventType == DataEventTypeEnum.REFRESH) {
    final String selectorParentPath = ZkPathConstants.buildRuleParentPath(changed.get(0).getPluginName());deleteZkPathRecursive(selectorParentPath);}for (RuleData data : changed) {
    final String ruleRealPath = ZkPathConstants.buildRulePath(data.getPluginName(), data.getSelectorId(), data.getId());if (eventType == DataEventTypeEnum.DELETE) {
    // 如果是删除操作,直接删除 zookeeper 目录deleteZkPath(ruleRealPath);continue;}final String ruleParentPath = ZkPathConstants.buildRuleParentPath(data.getPluginName());// 其他情况则创建或更新,将要更新的数据写入 zookeeper 的目录中createZkNode(ruleParentPath);//create or updateupsertZkNode(ruleRealPath, data);}}

org.dromara.soul.sync.data.zookeeper.ZookeeperSyncDataService

这个类在初始化时,使用 zkClient 订阅了很多 zookeeper 目录的变化消息,比如 rule :

	zkClient.subscribeChildChanges(groupParentPath, (parentPath, currentChildren) -> {
    if (CollectionUtils.isNotEmpty(currentChildren)) {
    List<String> addSubscribePath = addSubscribePath(childrenList, currentChildren);// Get the newly added node data and subscribe to that nodeaddSubscribePath.stream().map(addPath -> {
    String realPath = buildRealPath(parentPath, addPath);cacheRuleData(zkClient.readData(realPath));return realPath;}).forEach(this::subscribeRuleDataChanges);}});

每当相应 zookeeper 的目录有变化时,都会收到消息,此时重新拉取目录的状态和数据,即可完成数据同步的功能。

  相关解决方案