【Soul源码阅读】10.soul-admin 与 soul-bootstrap 同步机制之 zookeeper 解析(上)

Soul 网关(一)---- 架构设计简介、soul-admin、soul-bootstrap Soul 网关(一) Soul 是一个异步的,高性能的,跨语言的,响应式的API网关。今天先来整体了解一下 Soul 的结构。 Soul 架构图 两大部分:Soul-Admin(Soul 网关管理系统) 和 Soul-Cluster(网关Soul 集群) soul-admin (soul 网关的管理系统) soal-admin 依赖 MySQL,首先我们创建 soul 数据库,创建所需要的表,一共 12 个。 然后启动 soul-admin soul-admin 默认端口 9095 ,访问 http 阅读详情

目录

1.前情回顾

2.配置

2.1 soul-admin

2.2 soul-bootstrap

3.启动

3.1 启动 zookeeper

3.2 启动 soul-admin

3.2.1 注入 ZookeeperDataChangedListener 对象

3.2.2 注入 ZookeeperDataInit 对象


1.前情回顾

紧接着昨天的 websocket,今天来看下 zookeeper。

想知道websocket 相关的出门左转【Soul源码阅读】9.soul-admin 与 soul-bootstrap 同步机制之 websocket 解析

2.配置

数据同步策略官网链接 https://dromara.org/zh-cn/docs/soul/user-dataSync.html

因为数据同步方式是双方规定的,必须保持一致,所以修改配置也是 soul-admin 和 soul-bootstrap 都要改。

其实配置都是类似的,之前默认是 websocket,需要把 websocket 相关的配置注释掉,打开 zookeeper 相关配置。

2.1 soul-admin

# 修改前
soul:
  sync:
    websocket:
      enabled: true
#      zookeeper:
#          url: localhost:2181
#          sessionTimeout: 5000
#          connectionTimeout: 2000

# 修改后
soul:
  sync:
#    websocket:
#      enabled: true
    zookeeper:
      url: localhost:2181
      sessionTimeout: 5000
      connectionTimeout: 2000

配置文件对应 Bean:

@Data
@ConfigurationProperties(prefix = "soul.sync.zookeeper")
public class ZookeeperProperties {

    private String url;

    private Integer sessionTimeout;

    private Integer connectionTimeout;

    private String serializer;
}

2.2 soul-bootstrap

application-local.yml

# 修改前
soul:
    sync:
        websocket :
             urls: ws://localhost:9095/websocket
#        zookeeper:
#             url: localhost:2181
#             sessionTimeout: 5000
#             connectionTimeout: 2000

# 修改后
soul:
    sync:
#        websocket :
#             urls: ws://localhost:9095/websocket
        zookeeper:
             url: localhost:2181
             sessionTimeout: 5000
             connectionTimeout: 2000

配置文件对应 Bean:ZookeeperConfig

@Data
@ConfigurationProperties(prefix = "soul.sync.zookeeper")
public class ZookeeperConfig {

    private String url;

    private Integer sessionTimeout;

    private Integer connectionTimeout;

    private String serializer;
}

3.启动

3.1 启动 zookeeper

3.2 启动 soul-admin

基于昨天的分析,启动前可以在 DataSyncConfiguration.ZookeeperListener 里2个方法都打上断点,启动时一定会进。

// DataSyncConfiguration.java
@Configuration
public class DataSyncConfiguration {

...

    /**
     * The type Zookeeper listener.
     */
    @Configuration
    @ConditionalOnProperty(prefix = "soul.sync.zookeeper", name = "url")
    @Import(ZookeeperConfiguration.class)
    static class ZookeeperListener {
        @Bean
        @ConditionalOnMissingBean(ZookeeperDataChangedListener.class)
        public DataChangedListener zookeeperDataChangedListener(final ZkClient zkClient) {
            // 1.返回基于 zookeeper 的监听器对象
            return new ZookeeperDataChangedListener(zkClient);
        }
        @Bean
        @ConditionalOnMissingBean(ZookeeperDataInit.class)
        public ZookeeperDataInit zookeeperDataInit(final ZkClient zkClient, final SyncDataService syncDataService) {
            // 2.返回 zookeeper 初始化对象
            return new ZookeeperDataInit(zkClient, syncDataService);
        }
    }

...

}

3.2.1 注入 ZookeeperDataChangedListener 对象

1.返回基于 zookeeper 的监听器对象,并且注册到 spring 容器中,方便我们后续处理监听事件时使用。

2. ZookeeperDataInit,看名字是 zookeeper 数据的初始化,进到类里一探究竟。

3.2.2 注入 ZookeeperDataInit 对象

/**
 * The type Zookeeper data init.
 *
 * @author xiaoyu
 */
public class ZookeeperDataInit implements CommandLineRunner {

    private final ZkClient zkClient;

    private final SyncDataService syncDataService;

    /**
     * Instantiates a new Zookeeper data init.
     *
     * @param zkClient        the zk client
     * @param syncDataService the sync data service
     */
    public ZookeeperDataInit(final ZkClient zkClient, final SyncDataService syncDataService) {
        this.zkClient = zkClient;
        this.syncDataService = syncDataService;
    }

    @Override
    public void run(final String... args) {
        String pluginPath = ZkPathConstants.PLUGIN_PARENT;
        String authPath = ZkPathConstants.APP_AUTH_PARENT;
        String metaDataPath = ZkPathConstants.META_DATA;
        if (!zkClient.exists(pluginPath) && !zkClient.exists(authPath) && !zkClient.exists(metaDataPath)) {
            // 只有3个节点都不存在时,才同步全量数据
            syncDataService.syncAll(DataEventTypeEnum.REFRESH);
        }
    }
}

这个类实现了 CommandLineRunner 这个接口,并覆写了 run 方法。

run 方法会在 spring 启动容器后被调用。

此时会判断 zk 中是否存在3个节点,只有3个节点都不存在时,会同步全量数据。(第一次使用 zk,会同步全量数据)

// SyncDataServiceImpl.java
    @Override
    public boolean syncAll(final DataEventTypeEnum type) {
        // 同步 appAuth 数据
        appAuthService.syncData();
        // 同步 plugin 数据
        // 从 plugin 表中获取所有数据
        List<PluginData> pluginDataList = pluginService.listAll();
        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.PLUGIN, type, pluginDataList));
        // 同步 selector 数据
        // 从 selector 表中获取所有数据
        List<SelectorData> selectorDataList = selectorService.listAll();
        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.SELECTOR, type, selectorDataList));
        // 同步 rule 数据
        // 从 rule 表中获取所有数据
        List<RuleData> ruleDataList = ruleService.listAll();
        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.RULE, type, ruleDataList));
        // 同步 metaData 数据
        metaDataService.syncData();
        return true;
    }

1. 同步 appAuth 数据

// AppAuthServiceImpl.java
    @Override
    public SoulAdminResult syncData() {
        // 从 app_auth 表中获取所有数据
        List<AppAuthDO> appAuthDOList = appAuthMapper.selectAll();
        if (CollectionUtils.isNotEmpty(appAuthDOList)) {
            List<AppAuthData> dataList = appAuthDOList.stream().map(this::buildByEntity).collect(Collectors.toList());
            eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.APP_AUTH,
                    DataEventTypeEnum.REFRESH,
                    dataList));
        }
        return SoulAdminResult.success();
    }

如果数据不为空,发布事件(ConfigGroupEnum.APP_AUTH + DataEventTypeEnum.REFRESH)

2. 同步 pulgin 数据

发布事件(ConfigGroupEnum.PLUGIN + DataEventTypeEnum.REFRESH)

3. 同步 selector 数据

发布事件(ConfigGroupEnum.SELECTOR + DataEventTypeEnum.REFRESH)

4. 同步 rule 数据

发布事件(ConfigGroupEnum.RULE + DataEventTypeEnum.REFRESH)

5. 同步 metaData 数据

// MetaDataServiceImpl.java 
   @Override
    public void syncData() {
        // 从 meta_data 表中获取所有数据
        List<MetaDataDO> all = metaDataMapper.findAll();
        if (CollectionUtils.isNotEmpty(all)) {
            eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.META_DATA, DataEventTypeEnum.REFRESH, MetaDataTransfer.INSTANCE.mapToDataAll(all)));
        }
    }

发布事件(ConfigGroupEnum.META_DATA + DataEventTypeEnum.REFRESH)

发布事件后,就又回到了昨天就分析过的事件处理分发中心 DataChangedEventDispatcher,而这里的 listeners 就包含上面 3.2 中实例化的 ZookeeperDataChangedListener 对象。

// DataChangedEventDispatcher.java
    @Override
    @SuppressWarnings("unchecked")
    public void onApplicationEvent(final DataChangedEvent event) {
        for (DataChangedListener listener : listeners) {
            switch (event.getGroupKey()) {
                case APP_AUTH:
                    listener.onAppAuthChanged((List<AppAuthData>) event.getSource(), event.getEventType());
                    break;
                case PLUGIN:
                    listener.onPluginChanged((List<PluginData>) event.getSource(), event.getEventType());
                    break;
                case RULE:
                    listener.onRuleChanged((List<RuleData>) event.getSource(), event.getEventType());
                    break;
                case SELECTOR:
                    listener.onSelectorChanged((List<SelectorData>) event.getSource(), event.getEventType());
                    break;
                case META_DATA:
                    listener.onMetaDataChanged((List<MetaData>) event.getSource(), event.getEventType());
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + event.getGroupKey());
            }
        }
    }

在这里,虽然 websocket 配置文件注释掉了,但是 websocket 作为默认策略,即使没有配置也会注入。(@ConditionalOnProperty(name = "soul.sync.websocket.enabled", havingValue = "true", matchIfMissing = true) )

// DataSyncConfiguration.java
    @Configuration
    @ConditionalOnProperty(name = "soul.sync.websocket.enabled", havingValue = "true", matchIfMissing = true)
    @EnableConfigurationProperties(WebsocketSyncProperties.class)
    static class WebsocketListener

所以在 listeners 里会有2个实例,一个是 websocket 的,一个是 zookeeper 的。

这里 websocket 没有长连接,所以即使处理,在最后执行时由于 Set<Session> SESSION_SET 为空,也不会发送什么信息。

我们着重看下 zookeeper 是怎么处理的,ZookeeperDataChangedListener 实现了 DataChangedListener 接口,所以对于5种数据变更的处理都有其方法。

/**
 * Use zookeeper to push data changes.
 *
 * @author huangxiaofeng
 * @author xiaoyu
 */
public class ZookeeperDataChangedListener implements DataChangedListener {

    private final ZkClient zkClient;

    public ZookeeperDataChangedListener(final ZkClient zkClient) {
        this.zkClient = zkClient;
    }

    @Override
    public void onAppAuthChanged(final List<AppAuthData> changed, final DataEventTypeEnum eventType) {
        for (AppAuthData data : changed) {
            final String appAuthPath = ZkPathConstants.buildAppAuthPath(data.getAppKey());
            // delete
            if (eventType == DataEventTypeEnum.DELETE) {
                deleteZkPath(appAuthPath);
                continue;
            }
            // create or update
            upsertZkNode(appAuthPath, data);
        }
    }

    @SneakyThrows
    @Override
    public void onMetaDataChanged(final List<MetaData> changed, final DataEventTypeEnum eventType) {
        for (MetaData data : changed) {
            final String metaDataPath = ZkPathConstants.buildMetaDataPath(URLEncoder.encode(data.getPath(), "UTF-8"));
            // delete
            if (eventType == DataEventTypeEnum.DELETE) {
                deleteZkPath(metaDataPath);
                continue;
            }
            // create or update
            upsertZkNode(metaDataPath, data);
        }
    }

    @Override
    public void onPluginChanged(final List<PluginData> changed, final DataEventTypeEnum eventType) {
        for (PluginData data : changed) {
            final String pluginPath = ZkPathConstants.buildPluginPath(data.getName());
            // delete
            if (eventType == DataEventTypeEnum.DELETE) {
                deleteZkPathRecursive(pluginPath);
                final String selectorParentPath = ZkPathConstants.buildSelectorParentPath(data.getName());
                deleteZkPathRecursive(selectorParentPath);
                final String ruleParentPath = ZkPathConstants.buildRuleParentPath(data.getName());
                deleteZkPathRecursive(ruleParentPath);
                continue;
            }
            //create or update
            upsertZkNode(pluginPath, data);
        }
    }

    @Override
    public void onSelectorChanged(final List<SelectorData> changed, final DataEventTypeEnum eventType) {
        if (eventType == DataEventTypeEnum.REFRESH && !changed.isEmpty()) {
            final String selectorParentPath = ZkPathConstants.buildSelectorParentPath(changed.get(0).getPluginName());
            deleteZkPathRecursive(selectorParentPath);
        }
        for (SelectorData data : changed) {
            final String selectorRealPath = ZkPathConstants.buildSelectorRealPath(data.getPluginName(), data.getId());
            if (eventType == DataEventTypeEnum.DELETE) {
                deleteZkPath(selectorRealPath);
                continue;
            }
            final String selectorParentPath = ZkPathConstants.buildSelectorParentPath(data.getPluginName());
            createZkNode(selectorParentPath);
            //create or update
            upsertZkNode(selectorRealPath, data);
        }
    }

    @Override
    public void onRuleChanged(final List<RuleData> changed, final DataEventTypeEnum eventType) {
        if (eventType == DataEventTypeEnum.REFRESH && !changed.isEmpty()) {
            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) {
                deleteZkPath(ruleRealPath);
                continue;
            }
            final String ruleParentPath = ZkPathConstants.buildRuleParentPath(data.getPluginName());
            createZkNode(ruleParentPath);
            //create or update
            upsertZkNode(ruleRealPath, data);
        }
    }
    
    private void createZkNode(final String path) {
        if (!zkClient.exists(path)) {
            zkClient.createPersistent(path, true);
        }
    }
    
    /**
     * create or update zookeeper node.
     * @param path node path
     * @param data node data 
     */
    private void upsertZkNode(final String path, final Object data) {
        if (!zkClient.exists(path)) {
            zkClient.createPersistent(path, true);
        }
        zkClient.writeData(path, data);
    }
    
    private void deleteZkPath(final String path) {
        if (zkClient.exists(path)) {
            zkClient.delete(path);
        }
    }
    
    private void deleteZkPathRecursive(final String path) { 
        if (zkClient.exists(path)) {
            zkClient.deleteRecursive(path);
        }
    }
}

逻辑基本类似,都是先把节点路径拼接好,然后判断节点路径是否存在,如果不存在就先创建节点,然后在写数据。

到这里,就把数据库中已存在的节点及数据都写到初始化到 zookeeper 里了,如下图所示:

soul-bootstrap 端分析,见下篇。

 

 
第五天 Labview数据记录(5.4 EXCEL文件读写) Excel 文件读写在数据处理、自动化办公、数据分析等领域具有重要的意义。以下是 Excel 文件读写的主要应用场景和意义:1. 数据管理和整理;2. 自动化办公;3. 数据分析和可视化;4. 系统集成;5. 报表生成;6. 教育和培训;7. 实际应用场景。Excel 文件读写的意义在于提高数据处理的效率、减少人工操作、支持自动化办公、促进数据分析和可视化,以及实现系统之间的数据交互。无论是企业、组织还是个人,都可以通过 Excel 文件读写实现数据的高效管理和利用。 阅读详情

相关推荐

Flutter模块打包AAR集成Android原生项目实践

跨平台开发框架Flutter通过将UI组件渲染为原生代码实现高性能表现,其核心优势在于一套代码可同时运行在iOS和Android平台。在工程实践中,将Flutter模块打包为AAR(Android Archive)进行集成,成为混合开发的主流方案。这种方案既保留了原生项目的稳定性,又能渐进式引入Flutter的高效开发特性。通过配置MethodChannel实现原生与Dart代码通信,开发者可以灵活控制Flutter引擎生命周期,优化内存占用和渲染性能。对于电商、社交等需要快速迭代的业务场景,该方案能显著提

weixin_34025051的博客 397

【Soul源码阅读】9.soul-admin 与 soul-bootstrap 同步机制之 websocket 解析

1.前情回顾 在第4篇中,我们分析了 HTTP 用户业务系统接入 Soul 网关后,会调用 soul-admin 的注册接口,把需要网关代理的接口信息全部注册到 soul-admin 上,在最后,会通过 websocket 长连接,将soul-admin 接收到的接口信息同步给 Soul 网关(即 soul-bootstrap),今天就来接着继续分析,数据是怎么同步到 soul-bootstrap 的。 不清楚流程的可以出门左转看下第4篇文章【Soul源码阅读】4.HTTP 用户接入 Soul 调用 .

hellboy0621的博客 1080

Windows本地部署Ollama+qwen本地大语言模型Web交互界面并实现公网访问

本文主要介绍如何在Windows系统快速部署Ollama开源大语言模型运行工具,并安装Open WebUI结合cpolar内网穿透软件,实现在公网环境也能访问你在本地内网搭建的大语言模型运行环境。近些年来随着ChatGPT的兴起,大语言模型 LLM(Large Language Model)也成为了人工智能AI领域的热门话题,很多大厂也都推出了自己的大语言模型,并或多或少的开源了自己的大语言模型,今天就来分享一个最近很火,且对于小白来说比较好上手本地部署的运行本地LLM的工具Ollama。

迪之的博客 1650

google的api key调用次数是多少_并发、分布式、SQL编程中你遇到多少锁?距离高级工程师只差一步...

什么是锁,锁有哪些锁是java并发编程中最重要的同步机制。它可使临界区互斥执行,部分锁可以通过一定的手段进行消息通讯。Java中有哪些锁?分布式锁实现分布式锁常用实现有1. 数据库乐观锁;2. 基于Redis的分布式锁;3. 基于ZooKeeper的分布式锁,此章节着重介绍数据库乐观锁和基于redis的分布式锁的实现。乐观锁、悲观锁乐观锁:总是认为不会产生并发问题,每次去取数据的时候总认为不会有其...

weixin_39631951的博客 185

银河麒麟系统完美安装EasyConnect

Kylin V10桌面版完美安装EasyConnect

weixin_53874797的博客 1万+

Matlab安装硬件支持包、simulink离线安装硬件支持包安装,离线安装ESP32、stm32等安装包,Are you up-to-date on SoftWare Maintenance?

注意:如果提示出现“没有可从此位置安装的兼容支持包后,这个问题,请查看步骤5,是不是没有按照步骤5进行操作.一般情况下出现“没有可从此位置安装的兼容支持包”后,重新安装选择了默认路径就可以成功。如果不是很清楚,直接安装在默认的文件夹下面,即使这个文件夹下没有matlab相关的文件夹,也要这么下载,没有为什么,切记尽量按默认路径安装,更改下载的路径不成功,别怪我没提醒。:下载到哪里非常重要,如果下载的不是默认的路径下,就需要将其中这个的是这个archives文件夹,连同其他文件一并要复制出来,拷贝到。

pvmsmfchcs的博客 1744

Soul网关源码解析(番外2):soul-bootstrap启动流程

Soul网关源码解析(番外2):soul-bootstrap启动流程 Soul网关源码解析(番外2):soul-bootstrap启动流程Debug Bootstrap的方法Soul-Bootstrap启动流程WebHandler的初始化Plugins的初始化SyncDataService初始化小结参考 Debug Bootstrap的方法 对于Bootstrap启动过程中,具体哪些类参与,分别干了什么,在刚开始我们是不知道如何入手的,这里介绍一种方式,能让我们较快的找到突破口,当然这种方式对阅读其他

S_powerStone的博客 383

openlayers:实现在连续更改时间维度时如何平滑地重新加载层 (附完整源码)

openlayers:实现在连续更改时间维度时如何平滑地重新加载层 (附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 345

【Soul源码阅读】14.soul-admin 与 soul-bootstrap 同步机制之 nacos 解析(上)

目录 1.准备配套设施 2.配置 2.1 soul-admin 配置 2.2 soul-bootstrap 配置 3.启动服务 4.源码分析 1.准备配套设施 启动 MySQL、Nacos。 使用 docker 启动 Nacos(详情见官网github https://github.com/nacos-group/nacos-docker)。 Clone project git clone --depth 1 https://github.com/nacos-group/nacos-

hellboy0621的博客 424

prplOS适配USB LAN网卡

本文介绍了将USB LAN网卡(如rndis0)适配到prplOS的LAN管理流程。

四儿家的小祖宗的博客 321

ESP32-C3模组上跑通OTA升级(3)

ESP32-C3模组上跑通OTA升级(3)

phmatthaus的专栏 1351

【Soul源码阅读】11.soul-admin 与 soul-bootstrap 同步机制之 zookeeper 解析(下)

目录 3.3 启动 soul-bootstrap 接上篇【Soul源码阅读】10.soul-admin 与 soul-bootstrap 同步机制之 zookeeper 解析(上) 3.3 启动 soul-bootstrap 在上篇 2.2 小节中,提到了ZookeeperConfig 配置类,在代码中搜索使用的地方,找到ZookeeperSyncDataConfiguration,源码如下: /** * The type Zookeeper configuration. * * @...

hellboy0621的博客 282

RK3568平台(camera篇) MPP编码

同芯片的差异,为使用者提供统一的视频媒体处理接口(Media Process Interface,缩写 MPI)。瑞芯微提供的媒体处理软件平台(Media Process Platform,简称 MPP)是适用于瑞芯微芯片系列的。mpi_enc_test 的命令参数中,图像宽度(w)图像高度(h),码流类型(t)为强制要求参数,其他参。视频拷贝,缩放,色彩空间转换,场视频解交织(Deinterlace)数如输入文件(i),输出文件(o),编码帧数(n)等为可选参数。设置一些MPP的模式。

weixin_49303682的博客 7379

【Soul源码阅读】12.soul-admin 与 soul-bootstrap 同步机制之 http 长轮询解析(上)

1.前情回顾 紧接着前两天的 zookeeper,今天来看下 http 长轮询。 2.配置 数据同步策略官网链接https://dromara.org/zh-cn/docs/soul/user-dataSync.html 2.1 soul-admin 修改application.yml 配置文件,打开注释的代码: soul: sync: http: enabled: true 对应 Bean,默认 enabled 就是 true,只要配置 soul.s...

hellboy0621的博客 1072

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

soul源码阅读(十六)zookeeper bootstrap同步

目录 zookeeper watch机制 运行bootstrap的zookeeper同步 zookeeperbootstrap源码调试及解析 总结 zookeeper watch机制 根据官网我们了解到网关是通过zookeeper的 watch 机制去监听节点信息,并且启动的时候会读取一次全量信息,之后每次增量读取更新,那么我们先来对watch机制做下了解。 Watch的整体流程如下图所示,客户端先向ZooKeeper服务端成功注册想要监听的节点状态,同时客户端本地会存储该监听器相关的信息..

he_cha_bu的博客 295

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

soul源码分析数据同步篇之zookeeper同步流程

说明 本文代码基于soul 2021.2.4 master分支版本。 准备 请先阅读soul官方文档 数据同步原理,对soul数据同步原理有个基本的了解。 如何开启zookeeper同步策略 soul-admin的配置 application.yml中添加如下配置,或是在启动参数中添加--soul.sync.zookeeper.url=你的zk地址,然后重启服务: soul: sync: zookeeper: url: localhost:2181 session

evasnowind的专栏 348

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Soul网关源码阅读06-使用zookeeper同步数据(01)

启动 soul-admin、soul-bootstrap, 使用zookeeper同步数据到网关 一、配置环境 1、soul-admin 服务配置,需要重启服务 soul-admin/src/main/resources/application.yml soul: sync: zookeeper: url: localhost:2181 sessionTimeout: 5000 connectionTimeout: 2000 2、

xiaoxu的博客 283

Soul网关源码阅读07-使用zookeeper同步数据(02)

启动admin,与网关。 admin操作,使用zookeeper同步数据到网关 上一篇,通过soul-admin启动过程为入口,分析了soul-admin 启动就会同步网关数据 rule、metaData、selector、plugin 等到 zookeeper。 数据变化会发布 DataChangedEvent事件,监听事件将数据同步至zookeeper。 本篇接着上一篇继续跟踪源码分析zookeeper同步数据到网关原理: soul-admin 变更网关数据,跟踪数据同步过程。 soul-bootst

xiaoxu的博客 224

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

本次文章我们来探讨 Soul 中使用 zookeeper 的数据同步方式。 安装 zookeeper 首先准备安装包:https://zookeeper.apache.org/releases.html,下载的结果是 apache-zookeeper-3.6.2-bin.tar.gz,解压。 打开 conf 目录,在其中创建 zoo.cfg 文件,官方提供了一个示例文件 zoo_sample.cfg,可以仿照书写。主要需要修改的地方就是 数据文件目录这一行,改成我们自己需要的就行。 接下来打开 bin 目

rockpigL的博客 177

Soul网关源码阅读08-使用http长轮询同步数据(01)

前面两篇文章分析了zookeeper的数据同步原理,今天看一下体验http长轮询同步数据 一、环境配置 1、soul-admin 网关配置管理服务 soul-admin/src/main/resources/application.yml 打开http长轮询配置。 还有 soul-admin–>pom.xml 中的 websocket、zookeeper、nacos 等依赖无需删除,否则服务无法启动,仅需要把相应配置注释即可。 soul: sync: # websocket: #

xiaoxu的博客 311

Soul网关源码阅读(八)- ZK数据同步原理及源码解读

学习目标: 熟悉 soul 的数据同步机制中的 zk 同步 学习内容: 1.zk数据同步原理 2.配置 3.源码分析 学习时间:2021年1月23号 早6-8点 学习产出: zk数据同步原理 主要是依赖 zookeeper 的 watch 机制,soul-web 会监听配置的节点,soul-admin 在启动的时候,会将数据全量写入 zookeeper,后续数据发生变更时,会增量更新 zookeeper 的节点,与此同时,soul-web 会监听配置信息的节点,一旦有信息变更时,会更新本地缓存。 zk节

koutann2015的博客 217

Soul网关(十)---- 多soul-admin与多soul-bootstrap的数据同步

演示多个 soul-admin 和 多个 soul-bootstrap 数据同步 分别在 9095 端口、9096 端口启动 soul-admin; 分别在 9197 端口、9198端口启动 soul-bootstrap; 在其中一个 soul-admin 改动divide选择器其中的一个rule: 将精确匹配URL 由 /http/order/findById 改为 /http/order/findById111 改完之后可以看到另外一个 soul-admin 中此条规则也同步更新了。 ========

Loving you 785

微服务网关soul搭建

1.git clonehttps://github.com/Dromara/soul.git源码 2.安装zk 3.刷入 源码目录scripts/下soul.sql到数据库 4.修改soul-admin目录下相关参数 5.启动SoulAdminApplication ,访问http://localhost:8888/index.html输入 admin /123456 6...

工匠精神coding,终生学习 6090

【Soul源码阅读】15.soul-admin 与 soul-bootstrap 同步机制之 nacos 解析(下)

目录 1.准备 2.页面操作 3.跟踪源码 3.1 soul-admin 端 3.2 soul-bootstrap 端 上一篇讲到使用 nacos 同步策略,在项目启动时的同步机制,今天来看下在页面操作时,是怎么同步的。 1.准备 按照昨天的帖子(【Soul源码阅读】14.soul-admin 与 soul-bootstrap 同步机制之 nacos 解析(上)),把项目启动起来,soul-admin、soul-bootstrap 和 soul-examples-http 三个项目,当然还有

hellboy0621的博客 1130

dubbo注入找不到bean_Dubbo和Zookeeper入门案例

创建provier注意:类型必须为jar类型标签:pom文件exclusions标签的作用:1.根据构件坐标祛除在当前包内依赖的包<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http:...

weixin_36039921的博客 1038

Zookeeper中ZkClient及分布式锁的使用

1.zookeeper安装 直接查看:原文(windows操作系统下 springboot 集成 kafka)windows系统 2.zookeeper 启动zkCli.cmd操作 2.1 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容 2.2 创建一个新的 znode ,使用 create/usernamemyUserName 2.3 get /username 查看数据 2.4 delete /username 3.java简单使...

sinat_34338162的博客 860
上一篇: 【Soul源码阅读】9.soul-admin 与 soul-bootstrap 同步机制之 websocket 解析
下一篇: 【Soul源码阅读】11.soul-admin 与 soul-bootstrap 同步机制之 zookeeper 解析(下)
hellboy0621
博客等级 码龄9年 61粉丝 147原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值