本文主要是介绍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方法,是
AbstractDataHandler
的handle
方法
分析AbstractDataHandler的handle方法
- 事件类型(DataEventTypeEnum)有五种,分别是增删改 、刷新和Myself。REFRESH和Myself都是走刷新的逻辑
- DELETE
- CREATE
- UPDATE
- REFRESH
- MYSELF
handler
方法分别调用doRefresh
、doUpdate
、doDelete
方法- 以
doRefresh
方法为例,PluginDataHandler
的doRefresh
最终调用了
PluginDataSubscriber
的onSubscribe
方法。 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数据同步流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!