数据同步设计
本篇主要讲解数据同步原理,数据同步是指在 shenyu-admin 后台操作数据以后,使用何种策略将数据同步到 Apache ShenYu 网关。Apache ShenYu 网关当前支持ZooKeeper、WebSocket、Http长轮询、Nacos 、Etcd 和 Consul 进行数据同步。
数据同步的相关配置请参考用户文档中的 数据同步配置 。
背景
网关是流量请求的入口,在微服务架构中承担了非常重要的角色,网关高可用的重要性不言而喻。在使用网关的过程中,为了满足业务诉求,经常需要变更配置,比如流控规则、路由规则等等。因此,网关动态配置是保障网关高可用的重要因素。
在实际使用 Apache ShenYu 网关过程中,用户也反馈了一些问题:
- 依赖
Zookeeper,怎么使用Etcd、Consul、Nacos等其他注册中心? - 依赖
Redis、influxdb,没有使用限流插件、监控插件,为什么需要这些? - 配置同步为什么不使用配置中心?
- 为什么不能动态配置更新?
- 每次都要查询数据库,使用
Redis不就行了吗?
根据用户的反馈信息,我们对 Apache ShenYu 也进行了部分的重构,当前数据同步特性如下:
- 所有的配置都缓存在
Apache ShenYu网关内存中,每次请求都使用本地缓存,速度非常快。 - 用户可以在
shenyu-admin后台任意修改数据,并马上同步到网关内存。 - 支持
Apache ShenYu的插件、选择器、规则数据、元数据、签名数据等数据同步。 - 所有插件的选择器,规则都是动态配置,立即生效,不需要重启服务。
- 数据同步方式支持
Zookeeper、Http 长轮询、Websocket、Nacos、Etcd和Consul。
原理分析
下图展示了 Apache ShenYu 数据同步的流程,Apache ShenYu 网关在启动时,会从配置服务同步配置数据,并且支持推拉模式获取配置变更信息,然后更新本地缓存。管理员可以在管理后台(shenyu-admin),变更用户权限、规则、插件、流量配置,通过推拉模式将变更信息同步给 Apache ShenYu 网关,具体是 push 模式,还是 pull 模式取决于使用哪种同步方式。

在最初的版本中,配置服务依赖 Zookeeper 实现,管理后台将变更信息 push 给网关。而现在可以支持 WebSocket、Http长轮询、Zookeeper、Nacos、Etcd 和 Consul,通过在配置文件中设置 shenyu.sync.${strategy} 指定对应的同步策略,默认使用 WebSocket 同步策略,可以做到秒级数据同步。但是,有一 点需要注意的是,Apache ShenYu网关 和 shenyu-admin 必须使用相同的同步策略。
如下图所示,shenyu-admin 在用户发生配置变更之后,会通过 EventPublisher 发出配置变更通知,由 EventDispatcher 处理该变更通知,然后根据配置的同步策略(Http、WebSocket、Zookeeper、Nacos、Etcd、Consul),将配置发送给对应的事件处理器。
- 如果是
WebSocket同步策略,则将变更后的数据主动推送给shenyu-web,并且在网关层,会有对应的WebsocketDataHandler处理器来处理shenyu-admin的数据推送。 - 如果是
Zookeeper同步策略,将变更数据更新到Zookeeper,而ZookeeperSyncCache会监听到Zookeeper的数据变更,并予以处理。 - 如果是
Http同步策略,由网关主动发起长轮询请求,默认有90s超时时间,如果shenyu-admin没有数据变更,则会阻塞Http请求,如果有数据发生变更则响应变更的数据信息,如果超过60s仍然没有数据变更则响应空数据,网关层接到响应后,继续发起Http请求,反复同样的请求。
Zookeeper同步原理
基于 Zookeeper 的同步原理很简单,主要是依赖 Zookeeper 的 watch 机制。Apache ShenYu网关会监听配置的节点,shenyu-admin 在启动的时候,会将数据全量写入 Zookeeper,后续数据发生变更时,会增量更新 Zookeeper 的节点,与此同时,Apache ShenYu网关会监听配置信息的节点,一旦有信息变更时,会更新本地缓存。

Apache ShenYu 将配置信息写到zookeeper节点,是通过精心设计的,如果您想深入了解代码实现,请参考源码 ZookeeperSyncDataService。
WebSocket同步原理
WebSocket 和 Zookeeper 机制有点类似,将网关与 shenyu-admin 建立好 WebSocket 连接时,shenyu-admin 会推送一次全量数据,后续如果配置数据发生变更,则以增量形式将变更数据通过 WebSocket 主动推送给 Apache ShenYu网关。
使用 WebSocket 同步的时候,特别要注意断线重连,也就是要保持心跳。Apache ShenYu使用java-websocket 这个第三方库来进行websocket连接。
如果您想深入了解代码实现,请参考源码 WebsocketSyncDataService。
Http长轮询同步原理
Zookeeper和WebSocket 数据同步的机制比较简单,而 Http长轮询则比较复杂。 Apache ShenYu 借鉴了 Apollo