Soul源码解析(六)- webSocket数据同步

webSocket数据同步

Soul网关提供的三种数据同步方式

Soul网关提供了一下三种,可以任意选择

  1. 基于zookeeper的监听订阅模式;
  2. webSocket推送模式;
  3. 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);
  ...

代码结构目录

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35115942/article/details/112914309