分析前准备
spring事件机制
spring框架提供了事件发布订阅机制,由发布者、订阅者、事件三个关键要素组成,发布者发布事件后,由该事件的订阅者进行事件处理。
- 事件(所有事件均继承该类)
public abstract class ApplicationEvent extends EventObject {
private static final long serialVersionUID = 7099057708183571937L;
private final long timestamp = System.currentTimeMillis();
public ApplicationEvent(Object source) {
super(source);
}
public final long getTimestamp() {
return this.timestamp;
}
}
- 订阅者,也叫监听器,监听对应的事件
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E var1);
}
- 发布者
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
this.publishEvent((Object)event);
}
void publishEvent(Object var1);
}
该模式类似mq,mq可以支持发布者和消费者不在同一应用中,而使用spring事件机制时,发布者和订阅者必须在同一应用中
websocket原理
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
数据同步过程
- 客户端向soul-admin注册对应路由信息,
- soul-bootstrap启动时,会自动通过websocket向soul-admin发送请求全量路由信息的请求
- soul-admin接收到该请求后,会将全量插件等信息依次推送过soul-bootstrap
- soul-bootstrap接收到消息,会按消息类型存到对应的内存区域
- 当用户在soul-admin中进行相关规则变更时,会通过spring事件机制通知消费者发送websocket消息,soul-bootstrap接收到进行同步缓存更新
源码分析
首次启动全量同步
以下贴出关键源码信息
-
soul-bootstrap首次启动时,进行全量请求
通过soul-spring-boot-starter-sync-data-websocket自动配置,进入该类WebsocketSyncDataService
途中标红色部分构造socket客户端,如果连接多个soul-admin,配置多个,为关键代码,再看SoulWebsocketClient代码:
当首次连接上soul-admin时,会向soul-admin发送全量同步的信号。 -
再来看看soul-admin接到该请求处理时的逻辑:
图中该类是接收到soul-bootsrap发出全量同步时需要调用操作,进行全量同步的方法如下:
至此首次启动进行全量同步的过程基本完成
运行中变更同步
- 当soul-admin进行路由插件等信息变更时,对应的处理方法:
以RuleServiceImpl类分析,当soul-admin接收到客户端的注册信息时,会调用以下处理方法:
可以看到先将注册信息保存到数据库中后,然后发布对应消息事件,事件类如下
soul中该事件继承spring的ApplicationEvent事件,那么消费者或事件监听者接收到的处理逻辑是什么?通过分析发下,
该类即是消息消费者,又是监听分发器,监听器对应的实现如下:
通过不同监听器的实现,监听器中处理方法也是将消息按分类通过websocket发送出去。