Apache-shenYu源码阅读06-数据同步总体流程概览

706 阅读6分钟

Soul数据同步总体接口一览

之前已经讲过了基于websocket的大体的数据同步流程,在昨日阅读plugin模块相关类的时候,大体已经能串起来了,所以今日把也明白了之前在创建websocket连接时的动态载入的三个参数的作用PluginDataSubscriber,MetaDataSubscriber, AuthDataSubscriber
接下来让我们基于下面的流程图重新认识一下Soul网关数据同步模块的核心逻辑

事件的发布

Soul网关基于Spring提供的事件机制自定义了一个事件类型DataChangedEvent(核心重点),在页面或别的接口接入网关时,都会出发事件的发布,而事件的发布又分为APP_AUTH,META_DATA,RULE,SELECTOR,PLUGIN几种事件,这里需要注意事件类型的定义统一由ConfigGroupEnum维护,而DataChangedEvent的属性也包含了该类。

admin端事件的处理

在基于Spring的ApplicationEventListener,会统一交给DataChangedListener具体子类去实现,目前的实现方式有基于zookeeper的节点监听通讯、http长轮询、websocket双向通讯,基于nacos的配置通讯

各个子类对数据处理的实现方式各有千秋

举例说明

  • websocket 向bootstrap端的websocket的client端发送对应信息,增量同步
  • naocs 在admin端的本地维护了5个类型(即上述所述的APP_AUTH....等)的ConcurrentHashMap,无论哪种类型的数据变更,在NacosDataChangedListener的处理都是先修改处于admin端的map,然后在用发送配置的方式,将数据全量发送的nacos上,这里也可以猜测到基于nacos的数据同步是全量同步
  • zookeeper 在admin端处理数据是对存储在zookeeper上各个类型节点(存储的3个大节点格式为\soul\plugin....等)的增删改。(zk监听机制暂时没有测试过监听大节点,当大节点下小节点的变更针对于zk的监听机制监听到的是整个大节点变更的数据还是小节点变更的数据,这里对全量同步还是增量同步打个问号,还有待测试,印象里应该是监听到小节点变更)
  • http长轮询 在admin端处理数据是将5个类型(上述所述的APP_AUTH...等)的数据统一放到一个大的ConCurrentHashMap中,在初始化时会向bootstrap端同步一次数据,之后对数据的变更都直接从库中全量查取,核心点,定时线程池定时同步数据,md5校验判断数据是否需要推送,由此也可以看出该方式也是全量同步 逻辑还没仔细理 上面的逻辑应该有问题

bootstrap端事件的处理

在admin端的数据处理流程中我们可以看出,无论是采用那种数据同步的方式都是为了让bootstrap端感受到数据的变化,接下来让我们看看针对于各个同步类型bootstrap端是如何处理的?

举例说明

  • websocket 在使用websocket方式进行数据同步时,bootstrap会创建client与admin的server进行连接,通过双向通讯的方式完成数据的同步,核心类:WebsocketSyncDataService、WebsocketDataHandler。重点关注代码:策略+简单工厂+模板实现的数据处理,websocket的心跳保活机制
  • nacos 在使用nacos方式进行数据同步时,bootstrap会监听nacos的几个配置项,对数据传递的处理是直接进行先取消再发布的策略,这更加验证了nacos同步方式是全量同步的可能,核心类:NacosSyncDataService、NacosCacheHandler
  • zookeeper 在使用zookeeper方式进行数据同步时,bootstrap会监听zookeeper的对应的znode节点,这里需要注意的是监听的znode节点只有三类plugin、meta_data、auth,而selector、rule关联的是plugin下的子节点,在初始化时订阅了三个大节点,基于zookeeper的watch机制实现了数据变更的监听,只有一个类ZookeeperSyncDataService,重点学习:zk的监听机制
  • http长轮询 逻辑还没仔细理 暂不分析

针对于bootstrap端处理的核心要点

无论是使用任何方式同步数据在创建XXXSyncDataService类时,都会传递PluginDataSubscriber、MetaDataSubscriber、AuthDataSubscriber这样的实例数据,那么你可能会产生疑问这三种类型的数据到底是干啥的呢?

接下来让我们一一解惑

PluginDataSubscriber 插件数据订阅接口

无论采用数据同步的方式,针对于Plugin、Rule、SELECTOR的数据变更的处理都会由PluginDataSubscriber的子类CommonPluginDataSubscriber来实现,针对于CommonPluginDataSubscriber类来说,它不仅仅完成了在内存中数据的变更,还负责将各个数据变更通知告知给了对应的插件链实现,涉及到的类有PluginDataHandler 及其具体实现类,具体通知数据类型如下图所示。 针对于上图所示的具体子类实现的方法,未开展具体研究。

MetaDataSubscriber 元数据订阅接口

与PluginDataSubscriber类似,针对于META_DATA的数据处理,最后都是告知给了MetaDataSubscriber具体实现类做处理,此处的具体实现类如下图。

在上图中可以看出订阅元数据处理的实现主要是RPC相关 以及一个特殊的MetaDataAllSubscriber,在这里我们先打个问号,后期追溯到具体的插件链时再进行深入分析?

AuthDataSubscriber 鉴权数据订阅

AuthDataSubscriber类实现类只有一个SignAuthDataSubscriber,在这个实现类中主要定义了对SignAuthDataCache中缓存数据的更改,太体追了一个设计到该缓存的主要是sign插件。

数据同步总结

流程梳理

  • 在admin端数据处理大体可以认为就是在对应数据发生变化时,如何通知到bootstrap端。
  • 在bootstrap端的逻辑大体就是,当我的得知某个数据类型变更,通过实现的方式获取到变更的数据。

心得体会

  • 其实可以看出Soul的数据同步模块就是一个大模板,提供了多个顶级的接口来完成了整个数据的同步。
  • 在上文中还有一点没有提到,那就是在bootstrap初始化的时候,各个方式是如何在初始化时同步的全量数据。
  • 基于Soul同步数据的大模板模式,我们能否扩充别的数据同步类型?基于redis、文件、数据库、消息队列的广播???