webSocket数据同步
webSocket数据同步
Soul网关提供的三种数据同步方式
Soul网关提供了一下三种,可以任意选择
- 基于zookeeper的监听订阅模式;
- webSocket推送模式;
- http长轮询;
为什么需要数据同步?
- Soul网关是服务层和控制台分离的,而服务层又是可以集群部署的,存在数据一致性问题;
- 网关是公司流量入口,为了提升响应速度,所有的数据应该存在JVM内存中,这样每次请求的响应速度非常之快;
数据同步原理
Soul 网关在启动时,会从从配置服务同步配置数据,并且支持推拉模式获取配置变更信息,并且更新本地缓存。而管理员在管理后台,变更用户、规则、插件、流量配置,通过推拉模式将变更信息同步给 Soul 网关,具体是 push 模式,还是 pull 模式取决于配置。关于配置同步模块,其实是一个简版的配置中心。
webSocket数据同步原理
在网关启动的时候,系统会自动的进行一次全量的拉去admin配置;之后,每当admin的配置发生变化的时候,系统会出发webSocket的onMessage()
方法,onMessage()
方法会通知所有的订阅者并且更新JVM的配置缓存(这里使用到了一个发布订阅模式,可以参考之前写的Soul源码解析(二)- 发布订阅模式.);
// 消息变更触发webSocket
@Override
public void onMessage(final String result) {
handleResult(result);
}
...
// 通知所有订阅者更新JVM缓存
@SuppressWarnings("ALL")
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);
}
同时在使用webSocket的时候,为了防止连接断开,我们需要实现一个心跳检测和短线重连。
每个连接线程每10s 进行一次心跳检测,如果是断线则重新连接;
...
executor.scheduleAtFixedRate(() -> {
try {
// 每10s进行一次心跳检测
if (client.isClosed()) {
boolean reconnectSuccess = client.reconnectBlocking();
// 断线重连
if (reconnectSuccess) {
log.info("websocket reconnect is successful.....");
} else {
log.error("websocket reconnection is error.....");
}
}
} catch (InterruptedException e) {
log.error("websocket connect is error :{}", e.getMessage());
}
}, 10, 30, TimeUnit.SECONDS);
...