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

相关文章

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三