soul从入门到进阶05——soul-bootstrap数据同步流程

2024-01-22 12:18

本文主要是介绍soul从入门到进阶05——soul-bootstrap数据同步流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们在 soul-admin的数据同步流程中分析了admin的数据同步流程,这篇我们来看看soul-bootstrap的数据同步流程

启动 soul-bootstrap

打印如下日志,我们同样从日志着手来分析。

  • 日志中打印了 you use websocket sync soul data
  • 我们根据日志,找到WebsocketSyncDataConfiguration这个类
2021-01-19 21:19:48.461  INFO 20364 --- [           main] b.s.s.d.w.WebsocketSyncDataConfiguration : you use websocket sync soul data.......
2021-01-19 21:19:48.526  INFO 20364 --- [           main] o.d.s.p.s.d.w.WebsocketSyncDataService   : websocket connection is successful.....
2021-01-19 21:19:48.617  INFO 20364 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2021-01-19 21:19:49.202  INFO 20364 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 9195
2021-01-19 21:19:49.205  INFO 20364 --- [           main] o.d.s.b.SoulBootstrapApplication         : Started SoulBootstrapApplication in 13.767 seconds (JVM running for 14.489)
分析WebsocketSyncDataConfiguration
  • 这个类的代码非常简单,从名字上看出来是一个配置类。
  • 下面这一行表示 前缀(prefix是soul.sync.websocket的属性),配置的名字是urls。才会来加载这个类。对应配置文件中的属性
soul :sync:websocket :urls: ws://localhost:9095/websocket
@ConditionalOnProperty(prefix = "soul.sync.websocket", name = "urls")
  • websocketSyncDataService方法里,会加载一个WebsocketSyncDataService类。
分析WebsocketSyncDataService
  • 初步观察 WebsocketSyncDataService这个类。
  • 发现构造方法里的意图是根据url的数量,创建了对应数量的websocket 客户端,以及对应数量的线程池。线程池定时检测websocket客户端的连接状态。
  • 同时WebsocketSyncDataService实现了AutoCloseable接口,来进行资源的管理
分析SoulWebsocketClient
  • 点击WebSocketClient抽象类,然后查看抽象类的实现类。
  • 发现SoulWebsocketClient实现了WebSocketClient
  • onMessage是收到websocket消息之后调用的方法。
   @Overridepublic void onMessage(final String result) {handleResult(result);}
  • handlerResult方法是真正处理收到的信息的方法
 private void handleResult(final String result) {WebsocketData websocketData = GsonUtils.getInstance().fromJson(result, WebsocketData.class);ConfigGroupEnum groupEnum = ConfigGroupEnum.acquireByName(websocketData.getGroupType());String eventType = websocketData.getEventType();String json = GsonUtils.getInstance().toJson(websocketData.getData());websocketDataHandler.executor(groupEnum, json, eventType);}
  • ConfigGroupEnum里面有五组config 分别是
    • APP_AUTH
    • PLUGIN 插件
    • SELECTOR 选择器
    • RULE 规则
    • META_DATA 元数据
  • 最后一行,websocketDataHandler.executor(groupEnum, json, eventType) ,是核心逻辑
  • WebsocketDataHandler类里面的excutor方法如下
 public void executor(final ConfigGroupEnum type, final String json, final String eventType) {ENUM_MAP.get(type).handle(json, eventType);}
  • 这里的handle方法,是AbstractDataHandlerhandle方法
分析AbstractDataHandler的handle方法
  • 事件类型(DataEventTypeEnum)有五种,分别是增删改 、刷新和Myself。REFRESH和Myself都是走刷新的逻辑
    • DELETE
    • CREATE
    • UPDATE
    • REFRESH
    • MYSELF
  • handler方法分别调用doRefreshdoUpdatedoDelete方法
  • doRefresh方法为例,PluginDataHandlerdoRefresh最终调用了
    PluginDataSubscriberonSubscribe方法。
  • PluginDataSubscriber的实现类是CommonPluginDataSubscriber
以CommonPluginDataSubscriber为例,
  • onSubscribe方法调用subscribeDataHandler
  • 最终操作的是BaseDataCache
    private <T> void subscribeDataHandler(final T classData, final DataEventTypeEnum dataType) {Optional.ofNullable(classData).ifPresent(data -> {if (data instanceof PluginData) {PluginData pluginData = (PluginData) data;if (dataType == DataEventTypeEnum.UPDATE) {BaseDataCache.getInstance().cachePluginData(pluginData);Optional.ofNullable(handlerMap.get(pluginData.getName())).ifPresent(handler -> handler.handlerPlugin(pluginData));} else if (dataType == DataEventTypeEnum.DELETE) {BaseDataCache.getInstance().removePluginData(pluginData);Optional.ofNullable(handlerMap.get(pluginData.getName())).ifPresent(handler -> handler.removePlugin(pluginData));}} else if (data instanceof SelectorData) {SelectorData selectorData = (SelectorData) data;if (dataType == DataEventTypeEnum.UPDATE) {BaseDataCache.getInstance().cacheSelectData(selectorData);Optional.ofNullable(handlerMap.get(selectorData.getPluginName())).ifPresent(handler -> handler.handlerSelector(selectorData));} else if (dataType == DataEventTypeEnum.DELETE) {BaseDataCache.getInstance().removeSelectData(selectorData);Optional.ofNullable(handlerMap.get(selectorData.getPluginName())).ifPresent(handler -> handler.removeSelector(selectorData));}} else if (data instanceof RuleData) {RuleData ruleData = (RuleData) data;if (dataType == DataEventTypeEnum.UPDATE) {BaseDataCache.getInstance().cacheRuleData(ruleData);Optional.ofNullable(handlerMap.get(ruleData.getPluginName())).ifPresent(handler -> handler.handlerRule(ruleData));} else if (dataType == DataEventTypeEnum.DELETE) {BaseDataCache.getInstance().removeRuleData(ruleData);Optional.ofNullable(handlerMap.get(ruleData.getPluginName())).ifPresent(handler -> handler.removeRule(ruleData));}}});}
分析BaseDataCache
  • BaseDataCache里面有三个ConcurrentMap分别存储了PLUGIN、SELECTOR、RULE的信息
  • 也就是说对插件、选择器、规则的操作,最终反映到内存中是对这个BaseDataCache中三个ConcurrentMap的操作

这篇关于soul从入门到进阶05——soul-bootstrap数据同步流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/632936

相关文章

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

使用SpringBoot整合Sharding Sphere实现数据脱敏的示例

《使用SpringBoot整合ShardingSphere实现数据脱敏的示例》ApacheShardingSphere数据脱敏模块,通过SQL拦截与改写实现敏感信息加密存储,解决手动处理繁琐及系统改... 目录痛点一:痛点二:脱敏配置Quick Start——Spring 显示配置:1.引入依赖2.创建脱敏

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

详解如何使用Python构建从数据到文档的自动化工作流

《详解如何使用Python构建从数据到文档的自动化工作流》这篇文章将通过真实工作场景拆解,为大家展示如何用Python构建自动化工作流,让工具代替人力完成这些数字苦力活,感兴趣的小伙伴可以跟随小编一起... 目录一、Excel处理:从数据搬运工到智能分析师二、PDF处理:文档工厂的智能生产线三、邮件自动化:

Python数据分析与可视化的全面指南(从数据清洗到图表呈现)

《Python数据分析与可视化的全面指南(从数据清洗到图表呈现)》Python是数据分析与可视化领域中最受欢迎的编程语言之一,凭借其丰富的库和工具,Python能够帮助我们快速处理、分析数据并生成高质... 目录一、数据采集与初步探索二、数据清洗的七种武器1. 缺失值处理策略2. 异常值检测与修正3. 数据