soul网关学习数据同步方式之http长轮训
soul-admin 与 网关的数据通过http长轮训方式同步
参考官网: https://dromara.org/zh-cn/docs/soul/dataSync.html
同步原理
zookeeper、websocket 数据同步的机制比较简单,而 http 同步会相对复杂一些。Soul 借鉴了 Apollo、Nacos 的设计思想,取其精华,自己实现了 http 长轮询数据同步功能。注意:这里并非传统的 ajax 长轮询!
http 长轮询机制如上所示,soul-web 网关请求 admin 的配置服务,读取超时时间为 90s,意味着网关层请求配置服务最多会等待 90s,这样便于 admin 配置服务及时响应变更数据,从而实现准实时推送。
http 请求到达 sou-admin 之后,并非立马响应数据,而是利用 Servlet3.0 的异步机制,异步响应数据。首先,将长轮询请求任务 LongPollingClient 扔到 BlocingQueue 中,并且开启调度任务,60s 后执行,这样做的目的是 60s 后将该长轮询请求移除队列,即便是这段时间内没有发生配置数据变更。因为即便是没有配置变更,也得让网关知道,总不能让其干等吧,而且网关请求配置服务时,也有 90s 的超时时间。
如果这段时间内,管理员变更了配置数据,此时,会挨个移除队列中的长轮询请求,并响应数据,告知是哪个 Group 的数据发生了变更(我们将插件、规则、流量配置、用户配置数据分成不同的组)。网关收到响应信息之后,只知道是哪个 Group 发生了配置变更,还需要再次请求该 Group 的配置数据。有人会问,为什么不是直接将变更的数据写出?我们在开发的时候,也深入讨论过该问题,因为 http 长轮询机制只能保证准实时,如果在网关层处理不及时,或者管理员频繁更新配置,很有可能便错过了某个配置变更的推送,安全起见,我们只告知某个 Group 信息发生了变更。
同步流程分析
- soul-admin 更改同步数据方式
sync:
# websocket:
# enabled: true
# zookeeper:
# url: localhost:2181
# sessionTimeout: 5000
# connectionTimeout: 2000
http:
enabled: true
- 网关服务开启同步数据方式配置
sync:
# websocket :
# urls: ws://localhost:9095/websocket
# zookeeper:
# url: localhost:2181
# sessionTimeout: 5000
# connectionTimeout: 2000
http:
url : http://localhost:9095
- 启动 soul-admin 、soul-bootstrap 、http-example
-
修改selector信息看同步功能 符合预期
-
跟踪同步流程
-
继续跟踪
-
从调用站的最顶层开始
-
其他断点处都是通用处理逻辑,所以直接看这个HttpSyncDataService 里面的处理流程
-
入口开启去各个服务的任务(cas 处理了一波如果启动了任务就无需在启动了)
-
看下具体任务 (catch 的处理值得借鉴)
默认重试三次 出现异常超过重试次数时候休息时间较长5min 如果没有超过重试次数
睡眠时间短一些5s
- 继续跟踪下拉取数据 (这里看到了官网说的再去来一次二次确认的处理)
- 跟进去看下处理方式
总结
- 跟踪了http长轮训同步数据方式
- 分析了HttpSyncDataService 具体实现方式
- 通过目前这几种同步方式,可以看出抽象出监听数据变化接口,以及订阅数据变化接口,抽象通用处理逻辑,尤其是同步内存数据那里只需要替换不同实现类的原始数据同步方式,策略模式的具体应用。