数据同步原理

    数据同步的相关配置请参考用户文档中的 数据同步配置

    网关是流量请求的入口,在微服务架构中承担了非常重要的角色,网关高可用的重要性不言而喻。在使用网关的过程中,为了满足业务诉求,经常需要变更配置,比如流控规则、路由规则等等。因此,网关动态配置是保障网关高可用的重要因素。

    在实际使用 Apache ShenYu 网关过程中,用户也反馈了一些问题:

    • 依赖 Zookeeper,怎么使用 EtcdConsulNacos等其他注册中心?
    • 依赖 Redisinfluxdb,没有使用限流插件、监控插件,为什么需要这些?
    • 配置同步为什么不使用配置中心?
    • 为什么不能动态配置更新?
    • 每次都要查询数据库,使用Redis不就行了吗?

    根据用户的反馈信息,我们对 Apache ShenYu 也进行了部分的重构,当前数据同步特性如下:

    • 用户可以在 shenyu-admin 后台任意修改数据,并马上同步到网关内存。
    • 支持 Apache ShenYu 的插件、选择器、规则数据、元数据、签名数据等数据同步。
    • 所有插件的选择器,规则都是动态配置,立即生效,不需要重启服务。
    • 数据同步方式支持 ZookeeperHttp 长轮询WebsocketNacosEtcdConsul

    原理分析

    下图展示了 Apache ShenYu 数据同步的流程,Apache ShenYu 网关在启动时,会从配置服务同步配置数据,并且支持推拉模式获取配置变更信息,然后更新本地缓存。管理员可以在管理后台(shenyu-admin),变更用户权限、规则、插件、流量配置,通过推拉模式将变更信息同步给 Apache ShenYu 网关,具体是 push 模式,还是 pull 模式取决于使用哪种同步方式。

    数据同步原理 - 图2

    在最初的版本中,配置服务依赖 Zookeeper 实现,管理后台将变更信息 push 给网关。而现在可以支持 WebSocketHttp长轮询ZookeeperNacosEtcdConsul,通过在配置文件中设置 shenyu.sync.${strategy} 指定对应的同步策略,默认使用 webosocket 同步策略,可以做到秒级数据同步。但是,有一点需要注意的是,Apache ShenYu网关 和 shenyu-admin 必须使用相同的同步策略。

    如下图所示,shenyu-admin 在用户发生配置变更之后,会通过 EventPublisher 发出配置变更通知,由 EventDispatcher 处理该变更通知,然后根据配置的同步策略(http、weboscket、zookeeper、naocs、etcd、consul),将配置发送给对应的事件处理器。

    • 如果是 同步策略,则将变更后的数据主动推送给 shenyu-web,并且在网关层,会有对应的 WebsocketDataHandler 处理器来处理 shenyu-admin 的数据推送。
    • 如果是 zookeeper 同步策略,将变更数据更新到 zookeeper,而 ZookeeperSyncCache 会监听到 zookeeper 的数据变更,并予以处理。

    基于 zookeeper 的同步原理很简单,主要是依赖 zookeeperwatch 机制。Apache ShenYu网关会监听配置的节点,shenyu-admin 在启动的时候,会将数据全量写入 zookeeper,后续数据发生变更时,会增量更新 zookeeper 的节点,与此同时,Apache ShenYu网关会监听配置信息的节点,一旦有信息变更时,会更新本地缓存。

    Apache ShenYu 将配置信息写到zookeeper节点,是通过精心设计的,如果您想深入了解代码实现,请参考源码 ZookeeperSyncDataService

    WebSocket同步原理

    websocketzookeeper 机制有点类似,将网关与 shenyu-admin 建立好 websocket 连接时,shenyu-admin 会推送一次全量数据,后续如果配置数据发生变更,则以增量形式将变更数据通过 websocket 主动推送给 Apache ShenYu网关。

    使用 websocket 同步的时候,特别要注意断线重连,也就是要保持心跳。Apache ShenYu使用java-websocket 这个第三方库来进行websocket连接。 如果您想深入了解代码实现,请参考源码 WebsocketSyncDataService

    ZookeeperWebSocket 数据同步的机制比较简单,而 Http长轮询则比较复杂。 Apache ShenYu 借鉴了 ApolloNacos 的设计思想,取其精华,自己实现了 Http长轮询数据同步功能。注意,这里并非传统的 ajax 长轮询!

    数据同步原理 - 图5

    Http长轮询 机制如上所示,Apache ShenYu网关主动请求 shenyu-admin 的配置服务,读取超时时间为 90s,意味着网关层请求配置服务最多会等待 ,这样便于 shenyu-admin 配置服务及时响应变更数据,从而实现准实时推送。

    http 请求到达 shenyu-admin 之后,并非立马响应数据,而是利用 Servlet3.0 的异步机制,异步响应数据。首先,将长轮询请求任务 LongPollingClient 扔到 BlockingQueue 中,并且开启调度任务,60s 后执行,这样做的目的是 60s 后将该长轮询请求移除队列。因为即便是没有配置变更,也需要让网关知道,不能一直等待。而且网关请求配置服务时,也有 90s 的超时时间。

    shenyu-web 网关层接收到 http 响应信息之后,拉取变更信息(如果有变更的话),然后再次请求 shenyu-admin 的配置服务,如此反复循环。 如果您想深入了解代码实现,请参考源码 HttpSyncDataService

    Nacos同步原理

    Nacos的同步原理与Zookeeper基本类似,主要依赖于Nacos配置管理,各个配置节点的路径与Zookeeper类似。

    Apache ShenYu网关会监听配置的节点,启动时,如果Nacos中不存在配置节点,将同步全量的数据写入Nacos中,后序数据发送变更时,全量更新Nacos中的配置节点,与此同时,Apache ShenYu网关会监听配置信息的节点,一旦有信息变更时,会更新本地缓存。

    如果您想深入了解代码实现,请参考源码 NacosSyncDataServiceNacos官方文档

    Etcd 数据同步原理与Zookeeper类似,主要依赖于Etcdwatch机制,各个配置节点路径与Zookeeper相同。

    Etcd的原生API使用稍有点复杂,所有对其进行了一定的封装。

    Apache ShenYu网关会监听配置的节点,启动时,如果Etcd中不存在配置节点,将同步全量的数据写入Etcd中,后序数据发送变更时,增量更新Etcd中的配置节点,与此同时,Apache ShenYu网关会监听配置信息的节点,一旦有信息变更时,会更新本地缓存。

    如果您想深入了解代码实现,请参考源码 EtcdSyncDataService

    Consul同步原理

    Consul 数据同步原理是网关定时轮询 Consul 的配置中心,获取配置版本号与本地进行比对。

    如果您想深入了解代码实现,请参考源码 ConsulSyncDataService