New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nacos Client Failover Function Enhancement #11053
Comments
You mean you want to do failover extension for nacos-client? |
It can be implemented as an extension to support multiple kinds of failover data sources.
|
我们是通过redis缓存示例数据... |
我们是通过马上重启解决服务端不可用问题…… |
问题:
|
|
目前的实现在: nacos/client/src/main/java/com/alibaba/nacos/client/naming/backups/FailoverReactor.java Line 256 in 84b3afc
我们可以加个开关,容灾打开时,就不写,容灾关闭时,就定时写,保持容灾数据的更新。 |
我觉得没必要, disk就是一个插件的默认实现, 默认实现不从client测写入failover,只有用户创建了对应文件才生效。 如果其他的自定义插件要写磁盘, 你就在自定义插件中自己写就好了,不要加开关侵入到默认插件里面。 |
当failover发生改变时,为什么不进行通知listener呢?单单只作用于查询接口。 对于用户来说,如果订阅对应的实例,那么一定是想要监听这个实例的变化,如果failover内容发生了变化,查询相关实例明明发生了变化,但是listener却没有接收到回调,这是否有些不合常理呢? |
是的,也需要通知 |
目前这个设计好像是没有考虑这点的是吗?我看目前的话只有当关闭开关时才会进行通知~ |
或许我可以等该设计的pr合并后,再支持这个特性? |
@stone-98 更新了设计图,PR也会跟进更新 |
okk |
Merged, will be added as a pre beta feature in 2.3.1 |
需求背景
目前Nacos客户端有一个FailoverReactor来进行容灾文件的管理,可以通过在指定磁盘文件里写入容灾数据来进行客户端使用数据的覆盖。FailoverReactor目前会拦截Nacos客户端查询接口调用,以getAllInstances接口为例,目前FailoverReactor的工作流程如下图:
这里主要涉及到两个组件:
FailoverReactor和ServiceInfoHoler的交互机制如下:
这里和客户端容灾的相关逻辑主要是3个:
目前的方式有四个问题:
实现方案
上面提到的问题1、3和4都比较好解决,下面会一一阐述。针对问题2,一般在生产环境中,我们会考虑使用中心化的数据存储来进行容灾数据的存储和管理。我们可以将FailoverReactor依赖的数据 来源抽象为一个SPI接口FailoverDataSource,这个接口默认实现还是本地磁盘,但是用户可以实现这个SPI接口来使用自定义的容灾数据源。
接口和数据结构定义
FailoverDataSource的定义为:
各个方法的作用为:
FailoverSwitch的定义建议如下:
FailoverData的定义建议为:
以naming模块为例,NamingFailoverData扩展FailoverData:
NamingFailoverData里的容灾数据类型为ServiceInfo。
交互流程
FailoverReactor内部流程
FailoverReactor和FailoverDataSource、ServiceInfoHoler的交互机制优化为:
各个组件职责说明如下:
客户端查询请求流程
对于客户端的查询请求,其流程优化为:
这里的流程和之前的变化为:当从failoverReactor里拿不到容灾数据的时候,还是会去serviceInfoHolder里读取数据。这么做的目的是因为我们可能只配置部分服务进行容灾,其他的服务还是走serviceInfoHolder。
订阅接口事件通知流程
对于订阅接口,之前是不会受到容灾开关的影响,现在则也会在容灾开启时停止数据更新通知:
同时,在容灾关闭时,我们需要根据容灾期间数据是否发生变化来决定要不要触发订阅事件通知,我们可以把这个逻辑驾到上面提到的FailoverSwitchRefresher里:
在这里当FailoverSwitchRefresher轮询发现容灾关闭时,在清空FailoverReactor的内存数据之前,会触发FailoverReactor和ServiceInfoHolder的数据比较,如果发现数据不一致,则会触发ServiceInfoHolder发布对应的服务变更事件。
可观测性
我们可以定义个MultiGauge来存储FailoverReactor里目前生效的容灾数据内容,统计粒度为每个服务当前有多少个实例:
测试用例
以下场景需要进行测试:
The text was updated successfully, but these errors were encountered: