总系列目录地址
上篇soul插件实现
数据同步
-
网关承担大量业务请求,需要做个各种配置,比如流控规则,路由规则等,因此网关需要经常修改配置,而动态配置的网关就能做到不需要停止业务,随时进行更改。
-
soul支持热插拔,所有的插件的选择器和规则都是动态配置,那么如何进行数据同步呢?
-
soul1.x版本支持zookeeper,从2.x开始,支持websocket,http长轮询,eureka,默认使用websocket。
-
数据同步有推拉两种模式,在soul中,不通的数据同步方式使用不通的模式,websocket使用推模式,zookeeper使用拉模式,这两种模式是推荐使用的,因为websocket和zookeeper第一次全量更新,后面都是增量更新数据。
soul网关设计
- 官网代码大概逻辑,使用发布订阅模式实现数据的关联
数据同步自动配置
public class DataSyncConfiguration {
@Configuration
@ConditionalOnProperty(name = "soul.sync.websocket.enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(WebsocketSyncProperties.class)
static class WebsocketListener {
@Bean
@ConditionalOnMissingBean(WebsocketDataChangedListener.class)
public DataChangedListener websocketDataChangedListener() {...}
@Bean
@ConditionalOnMissingBean(WebsocketCollector.class)
public WebsocketCollector websocketCollector() {...}
@Bean
@ConditionalOnMissingBean(ServerEndpointExporter.class)
public ServerEndpointExporter serverEndpointExporter() {...}
}
}
发布推送,通过前端触发
- ApplicationEventPublisher
Spring 提供的事件发布类,是ApplicationContext的父接口之一。同时配置使用的有ApplicationEventPublisherAware和ApplicationListener使用。
初始化位置org.dromara.soul.admin.service.sync.SyncDataServiceImpl。这个实现SyncDataService,定义了所有服务类,包括认证服务,插件服务,选择器服务,规则服务等。所有的服务都发布到ApplicationEventPublisher里面。
public interface SyncDataService {
boolean syncAll(DataEventTypeEnum type);
boolean syncPluginData(String pluginId);
}
监听器
- ApplicationListener
org.dromara.soul.admin.listener.DataChangeEventDispatcher类实现数据监听,监听所有类型的数据。
DataChangedEvent 继承了 ApplicationEvent
public class DataChangeEventDispatcher {
public void onApplicationEvent(final DataChangedEvent event) {
for (DataChangedListener listener : listeners) {
switch (event.getGroupKey()) {
case APP_AUTH:
// do something
break;
case PLUGIN:
// do something
break;
case RULE:
// do something
break;
case SELECTOR:
// do something
break;
case META_DATA:
// do something
break;
default:
// do something
}
}
}
}
- websocket方式
经过DataChangeEventDispatcher的过滤,针对不同类型的服务使用不同的更新方式。
WebsocketCollector是soul-admin里面的websocket服务
public class WebsocketDataChangedListener
public void onPluginChanged(final List<PluginData> pluginDataList, final DataEventTypeEnum eventType) {
WebsocketData<PluginData> websocketData =
new WebsocketData<>(ConfigGroupEnum.PLUGIN.name(), eventType.name(), pluginDataList);
// 监听到插件类型的更改,执行数据同步
WebsocketCollector.send(GsonUtils.getInstance().toJson(websocketData), eventType);
}
public void onSelectorChanged(final List<SelectorData> selectorDataList, final DataEventTypeEnum eventType) {...}
public void onRuleChanged(final List<RuleData> ruleDataList, final DataEventTypeEnum eventType) {...}
...
}
接收端:websocket
- 在网关接收 org.dromara.soul.plugin.sync.data.websocket.client.SoulWebsocketClient
public final class SoulWebsocketClient extends WebSocketClient { private void handleResult(final String result) { // 在此接受到消息,并执行 } }
总结
根据官网的流程大致可以梳理处理,但是后面websocket接受端已经改过,下面是重新画的流程图。具体细节没有看。
总的来说数据同步是基于发布订阅模式,对所有不同的实现都统一publish,同时所有实现都不同的监听实现DataChangedListener。
listener会把消息发送到网关,具体使用什么方式要看配置。websocket使用的是java-websocket接收数据。