Soul网关的探活--基于zookeeper同步数据的解析

Soul网关的探活,主要分为两部分,第一部分是soul admin探活。一部分是soul-admin同步数据到网关层soul-boostrap。本文以一个http客户端宕机之后的探活为例

Soul-admin探活

Soul-admin 探活这部分主要是依赖soul-admin中的UpstreamCheckService来实现的。

  /**
     * Setup selectors of divide plugin.
     */
    @PostConstruct
    public void setup() {
        PluginDO pluginDO = pluginMapper.selectByName(PluginEnum.DIVIDE.getName());
        if (pluginDO != null) {
            ListselectorDOList = selectorMapper.findByPluginId(pluginDO.getId());
            for (SelectorDO selectorDO : selectorDOList) {
                ListdivideUpstreams = GsonUtils.getInstance().fromList(selectorDO.getHandle(), DivideUpstream.class);
                if (CollectionUtils.isNotEmpty(divideUpstreams)) {
                    UPSTREAM_MAP.put(selectorDO.getName(), divideUpstreams);
                }
            }
        }
        if (check) {
            new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), SoulThreadFactory.create("scheduled-upstream-task", false))
                    .scheduleWithFixedDelay(this::scheduled, 10, scheduledTime, TimeUnit.SECONDS);
        }
    }

基于Spring的注解和线程池实现了,从程序开始每隔十秒探活的机制,探活的主要实现是UpstreamCheckUtils.checkUrl方法中实现了,确定了最终是否可达或者可以连接。而最终将消息探活,传递到网关端是通过前文说过多次的Spring的事件机制完成的

                eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.SELECTOR, DataEventTypeEnum.UPDATE,
                                                                 Collections.singletonList(selectorData)));

可以看到这里的选择选择器按钮,由于这里使用的是zookeeper同步
Soul网关的探活--基于zookeeper同步数据的解析_zookeeper
最终我们执行的是ZookeeperDataChangedListener的onSelectorChanged方法

网关SoulBoostrap获取数据进行处理

在ZookeeperSyncDataConfiguration中直接加载了ZookeeperSyncDataService类,并且在构造方法中就利用了ZKclient能够监听属性改变的特性
最后使用的是

   private void subscribeSelectorDataChanges(final String path) {
        zkClient.subscribeDataChanges(path, new IZkDataListener() {
            @Override
            public void handleDataChange(final String dataPath, final Object data) {
                cacheSelectorData((SelectorData) data);
            }

            @Override
            public void handleDataDeleted(final String dataPath) {
                unCacheSelectorData(dataPath);
            }
        });
    }

来更新网关中的选择器数据。最后使用的是CommonPluginDataSubscriber中的subscribeDataHandler方法,这个方法在SoulConfiguration中就利用ObjectProvider获取到了ObjectProvider<List