目录
1、同步流程介绍
这是读源码的过程中梳理出来的一张流程图,为websocket同步策略,soul-admin端的源码分析流程图。接下来我们一个个介绍。
DataSyncConfiguration初探
@Configuration
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() {
return new WebsocketDataChangedListener();
}
@Bean
@ConditionalOnMissingBean(WebsocketCollector.class)
public WebsocketCollector websocketCollector() {
return new WebsocketCollector();
}
@Bean
@ConditionalOnMissingBean(ServerEndpointExporter.class)
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
}
没有将DataSyncConfiguration整个类都给贴出来哈,整个配置类做的一件事情就是根据配置文件从zookeeper同步、websocket同步、http长轮询、nacos同步四种策略中选择一种,然后进行注册初始化。以上贴出来的是websocket策略同步注入spring管理的几个bean对象,接下来一一认识下:
- WebsocketDataChangedListener
这个类实现了一个接口DataChangedListener,实现了onPluginChanged,onSelectorChanged,onRuleChanged,onAppAuthChanged,onMetaDataChanged这几个方法,这几个方法里做的一件事件就是拿到websocetdata数据后,用websocketcolletor对象发送数据到网关,这几个api方法在哪被调用到呢?下面继续分析。
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);
}
- WebsocketCollector
首先可以看到这个类加了个注解@ServerEndpoint(value = "/websocket"),首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。。然后这个类里的方法介绍如下:
onOpen:连接建立成功调用的方法,网关每次启动会跟admin建立连接,就会调用这个方法。
onMessage:收到客户端消息后调用的方法,网关首次启动会调用这个方法,admin会进行全量的同步。
onClose:连接关闭调用的方法
onError:发生错误时调用
send:自定义发送消息,这个方法就是我们分析上个WebsocketDataChangedListener做changed更新的时候会调用。
- ServerEndpointExporter
这个bean的注入就是为了去自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。
启动一个datachangeEvent事件的监听器
首先来了解下ApplicationListener。ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制。如果容器中存在ApplicationListener的Bean,当ApplicationContext调用publishEvent方法时,对应的Bean的onApplicationEvent会被触发。这一过程是典型的观察者模式的实现。
DataChangedEvent实现了ApplicationEvent定义了一个数据更新的事件。
DataChangedEventDispatcher实现了ApplicationListener,并且绑定了DataChangedEvent事件,那么按照定义,每次如果有ApplicationContext调用publishEvent方法时,会触发DataChangedEventDispatcher.onApplicationEvent会被触发。另外实现InitializingBean接口,那么会在初始化bean的时候调用afterPropertiesSet()方法,在该方法里会去获取DataChangedListener实例化对象,在websocket同步中就是WebsocketDataChangedListener。
admin页面增删改查
以更新一个插件的开关为例,进行源码介绍,会进入updatePlugin方法,然后调用pluginService.createOrUpdate(pluginDTO)。
service方法里会更新数据库,且发送一个更新事件。
DataChangedEventDispatcher.onApplicationEvent()就会被触发。
然后执行WebsocketDataChangedListener.onPluginChanged发送消息。
启动后全量同步
soul网关启动过后会先跟admin创建连接,此时我们会在admin的日志中看到websocket on open successful....代表已经连接成功。
紧接着soul网关会请求一个消息,admin收到后就会向发送发送全量同步。
会查所有的插件以及选择器,规则等发送给到soul网关。