Nacos注册中心客户端容灾

news2024/11/24 18:50:41

目前Nacos客户端有一个FailoverReactor来进行容灾文件的管理,可以通过在指定磁盘文件里写入容灾数据来进行客户端使用数据的覆盖。FailoverReactor目前会拦截Nacos客户端查询接口调用,以getAllInstances接口为例,目前FailoverReactor的工作流程如下图:


这里主要涉及到两个组件:

  • FailoverReactor:容灾数据管理类,负责容灾开关和数据的加载和刷新;
  • ServiceInfoHoler:默认的服务数据管理类,持有一份内存服务数据缓存,负责处理Nacos服务端的推送的最新数据;

FailoverReactor和ServiceInfoHoler的交互机制如下:

这里和客户端容灾的相关逻辑主要是3个:

  1. FailoverReactor会定期读取磁盘容灾开关文件;
  2. 当容灾开关打开时,FailoverReactor会从磁盘里加载容灾数据文件,同时用户调用查询请求时就会优先使用容灾文件里的数据;
  3. FailoverReactor会定期从ServiceInfoHolder拿到最新的内存数据,保存到容灾磁盘数据文件里;

目前的方式有四个问题:

  1. 无法人工覆盖容灾数据,当前是定期将ServiceInfoHolder里的数据进行持久化作为容灾数据。即使手动修改了容灾数据磁盘文件内容,也会被覆盖为ServiceInfoHolder里的数据;
  2. 基于磁盘的容灾缓存有一些限制,比如服务的订阅者有多个机器实例时,如果需要打开容灾开关,需要运维批量修改机器的文件;
  3. subscribe接口不会使用FailoverReactor里的数据;
  4. 容灾数据的可观测性也需要优化。

实现方案

上面提到的问题1、3和4都比较好解决,下面会一一阐述。针对问题2,一般在生产环境中,我们会考虑使用中心化的数据存储来进行容灾数据的存储和管理。我们可以将FailoverReactor依赖的数据 来源抽象为一个SPI接口FailoverDataSource,这个接口默认实现还是本地磁盘,但是用户可以实现这个SPI接口来使用自定义的容灾数据源。

接口和数据结构定义

FailoverDataSource的定义为:

public interface FailoverDataSource {

     FailoverSwitch getSwitch();

     Map<String, FailoverData> getFailoverData();
}

各个方法的作用为:

  • FailoverSwitch getSwitch():获取当前的容灾开关;
  • Map<String, FailoverData> getFailoverData():获取当前的容灾数据,返回一个map,key是服务名,value为对应服务的容灾数据;

FailoverSwitch的定义建议如下:

public class FailoverSwitch {

    private boolean enabled;
}
  • enabled:容灾是否打开;

FailoverData的定义建议为:

public abstract class FailoverData {

    private DataType dataType;
    
    private Object data;
    
    protected FailoverData(Object data, DataType dataType) {
        this.data = data;
        this.dataType = dataType;
    }

    enum DataType {
        naming,
        config
    }
}
  • dataType:容灾数据类型,这里因为需要综合考虑配置模块的容灾,所以使用抽象类定义了naming和config两种容灾数据类型;
  • data:容灾数据,子类设置具体类型;

以naming模块为例,NamingFailoverData扩展FailoverData:

public class NamingFailoverData extends FailoverData {

    private NamingFailoverData(ServiceInfo serviceInfo) {
        super(serviceInfo, DataType.naming);
    }

    public static NamingFailoverData newNamingFailoverData(ServiceInfo serviceInfo) {
        return new NamingFailoverData(serviceInfo);
    }
}

NamingFailoverData里的容灾数据类型为ServiceInfo。

交互流程

FailoverReactor内部流程

FailoverReactor和FailoverDataSource、ServiceInfoHoler的交互机制优化为:

各个组件职责说明如下:

  • FailoverReactor:存储容灾缓存数据,管理容灾开关定时任务和容灾数据更新定时任务;
  • FailoverSwitchRefresher:定时(每5秒)从容灾数据源查询容灾开关,根据容灾开关的值进行相应操作:
    • 若容灾打开:从容灾数据源查询容灾数据FailoverDataSource,保存到FailoverReactor的内存容灾数据map里;
    • 若容灾关闭:清空FailoverReactor的内存容灾数据map;
  • FailoverDataSource:存储容灾数据,前文已经提及;
  • ServiceInfoHoler:默认情况下服务数据的管理,前文已经提及;

客户端查询请求流程

对于客户端的查询请求,其流程优化为:

这里的流程和之前的变化为:当从failoverReactor里拿不到容灾数据的时候,还是会去serviceInfoHolder里读取数据。这么做的目的是因为我们可能只配置部分服务进行容灾,其他的服务还是走serviceInfoHolder。

订阅接口事件通知流程

对于订阅接口,之前是不会受到容灾开关的影响,现在则也会在容灾开启时停止数据更新通知:

public ServiceInfo processServiceInfo(ServiceInfo serviceInfo) {
        ...
        if (changed) {
            NAMING_LOGGER.info("current ips:({}) service: {} -> {}", serviceInfo.ipCount(), serviceInfo.getKey(),
                    JacksonUtils.toJson(serviceInfo.getHosts()));
            // 判断容灾开关是否打开,打开时不发布事件:
            if (!failoverDataSource.getFailoverSwitch().isEnabled()) {
                NotifyCenter.publishEvent(new InstancesChangeEvent(notifierEventScope, serviceInfo.getName(), serviceInfo.getGroupName(),
                        serviceInfo.getClusters(), serviceInfo.getHosts()));
            }
            DiskCache.write(serviceInfo, cacheDir);
        }
        return serviceInfo;
    }

同时,在容灾关闭时,我们需要根据容灾期间数据是否发生变化来决定要不要触发订阅事件通知,我们可以把这个逻辑驾到上面提到的FailoverSwitchRefresher里:

在这里当FailoverSwitchRefresher轮询发现容灾关闭时,在清空FailoverReactor的内存数据之前,会触发FailoverReactor和ServiceInfoHolder的数据比较,如果发现数据不一致,则会触发ServiceInfoHolder发布对应的服务变更事件。

可观测性

我们可以定义个MultiGauge来存储FailoverReactor里目前生效的容灾数据内容,统计粒度为每个服务当前有多少个实例:

MultiGauge failoverInstanceCounts = MultiGauge.builder("nacos_naming_client_failover_instances").register(Metrics.globalRegistry);

Set<String> serviceNames = failoverDataSource.getSwitch().getServiceNames();
Map<String, FailoverData> failoverDataMap = failoverDataSource.getFailoverData();

failoverInstanceCounts.register(serviceNames.stream().map(serviceName -> MultiGauge.Row.of(Tags.of("service_name", serviceName), ((ServiceInfo)failoverDataMap.get(serviceName)).ipCount())).collect(Collectors.toList()), true);

测试用例

以下场景需要进行测试:

  • 打开容灾开关后,对于包含在容灾的服务列表里的服务,Nacos服务端数据变化不影响客户端查询和订阅;
  • 关闭容灾开关后,对于所有服务客户端查询到最新数据;
  • 关闭容灾开关后,若订阅的服务数据在容灾期间有变化,会触发一次订阅通知;
  • 设置容灾的服务列表,不在服务列表里的不会使用容灾数据;
  • 使用自定义的容灾实现,可以被加载并运行;

原文出自:Nacos官网 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1297110.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app实现安卓原生态调用身份证阅读器读卡库读身份证和社保卡、银行卡、IC卡等功能

DONSEE系列多功能读写器Android Uniapp API接口规范V1.0.0 本项目Uniapp调用了身份证读卡器的库文件&#xff1a;DonseeDeviceLib-debug.aar&#xff0c;该库放到nativeplugins\donsee-card\android&#xff0c;然后会自动加载。SDK会自动检查是否拥有USB设备权限&#xff0c;…

2023五岳杯量子计算挑战赛数学建模思路+模型+代码+论文

赛题思路&#xff1a;12月6日晚开赛后第一时间更新&#xff0c;获取见文末名片 “五岳杯”量子计算挑战赛&#xff0c;是国内专业的量子计算大赛&#xff0c;也是玻色量子首次联合移动云、南方科技大学共同发起的一场“企校联名”的国际竞赛&#xff0c;旨在深度融合“量子计算…

人工智能教程(三):更多有用的 Python 库

目录 前言 推荐 JupyterLab 入门 复杂的矩阵运算 其它人工智能和机器学习的 Python 库 前言 在本系列的上一篇人工智能教程&#xff08;二&#xff09;&#xff1a;人工智能的历史以及再探矩阵中&#xff0c;我们回顾了人工智能的历史&#xff0c;然后详细地讨论了矩阵。在…

二维数组附近遍历所有值

二维数组附近遍历所有值 假如以56点为中心&#xff0c;上下左右近距离遍历附近值&#xff0c;看代码&#xff0c;代码把思路写出来了&#xff0c;边界问题暂不处理。 #include<iostream> using namespace std;void FindNearPos(int (*int_arr)[10] , int p_row , int …

Linux centos8安装JDK1.8、tomcat

一、安装jdk 1.如果之前安装过jdk&#xff0c;先卸载掉旧的 rpm -qa | grep -i jdk 2.检查yum中有没有java1.8的包 yum list java-1.8* 3.yum安装jdk yum install java-1.8.0-openjdk* -y 4.验证 二、安装tomcat Index of /tomcat 可以在这里选择你想要安装的tomcat版本…

【vtkWidgetRepresentation】第七期 vtkImplicitPlaneRepresentation

很高兴在雪易的CSDN遇见你 前言 本文分享vtkImplicitPlaneRepresentation源码剖析&#xff0c;及相关的实例&#xff0c;该接口主要用于切割交互&#xff0c;希望对各位小伙伴有所帮助&#xff01; 感谢各位小伙伴的点赞关注&#xff0c;小易会继续努力分享&#xff0c;一起…

线上盲盒小程序,开启互联网盲盒时代

近年来&#xff0c;盲盒经济在国内非常火爆&#xff0c;各类盲盒品牌层出不穷&#xff0c;深受国内外年轻人、消费者的喜爱。 目前&#xff0c;根据数据显示&#xff0c;盲盒市场不仅在线下异常火热&#xff0c;线上盲盒也是成为了大众的新选择。各类电商平台中盲盒的成交额更…

C++ Qt开发:Qt的安装与配置

Qt是一种C编程框架&#xff0c;用于构建图形用户界面&#xff08;GUI&#xff09;应用程序和嵌入式系统。Qt由Qt公司&#xff08;前身为Nokia&#xff09;开发&#xff0c;提供了一套跨平台的工具和类库&#xff0c;使开发者能够轻松地创建高效、美观、可扩展的应用程序。其被广…

元宇宙vr党建云上实景展馆扩大党的影响力

随着科技的飞速发展&#xff0c;VR虚拟现实技术已经逐渐融入我们的日常生活&#xff0c;尤其在党建领域&#xff0c;VR数字党建展馆更是成为引领红色教育新风尚的重要载体。今天&#xff0c;就让我们一起探讨VR数字党建展馆如何提供沉浸式体验&#xff0c;助力党建工作创新升级…

无头浏览器与Selenium:探索无界爬虫的奇妙世界

selenium设置无头浏览器 背景 ​ 我们之前的selenium都是浏览器驱动自动打开一个网页&#xff0c;执行相关操作&#xff0c;其实也可以让其后台显示&#xff0c;不用在前台显示。 ​ 要设置无头浏览器&#xff0c;可以使用Selenium的Headless模式。在Headless模式下&#xf…

解读 | 阿里通义千问模型全尺寸开源 “诚意满满“背后的名与利

大家好&#xff0c;我是极智视界&#xff0c;欢迎关注我的公众号&#xff0c;获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码和资源下载&#xff0c;链接&#xff1a;https://t.zsxq.com/0aiNxERDq 12 月 1 日阿里开源…

【深度挖掘Java性能调优】「底层技术原理体系」深入挖掘和分析如何提升服务的性能以及执行效率(性能三大定律)

深入挖掘和分析如何提升服务的性能以及执行效率 前提介绍知识要点 性能概述教你看懂程序的性能案例介绍性能指标性能的参考指标性能瓶颈&#xff08;木桶原理&#xff09; 性能分析三大定律Amdahl定律计算公式参数解释案例分析定律总结 Gustafson定律与Amdahl定律相对立Gustafs…

Postman和Apifox针对不同环境、全局变量的使用与比较

文章目录 一、Postman1、配置环境和全局变量2、验证3、存在问题分析 二、Apifox1、配置环境和全局参数2、创建公共脚本3、测试 总结 一、Postman 1、配置环境和全局变量 在Postman的界面中&#xff0c;点击"Environment"&#xff0c;添加我们需要的环境&#xff0c…

基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(二)

目录 前言引言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理1&#xff09;数据介绍2&#xff09;数据测试3&#xff09;数据处理 相关其它博客工程源代码下载其它资料下载 前言 博主前段时间发布了一篇有关方言识别和分类模型训练的博客&#xff0c;在读者…

10 大 Android 手机系统修复软件深度评测

您的新 Android 手机可能因其令人兴奋的性能而印象深刻。然而&#xff0c;随着时间的推移&#xff0c;您可能会发现系统有些地方与以前不太一样。您可能会遇到屏幕无响应、 Android应用程序崩溃、连接问题、电池耗尽等现象。 10 大 Android 手机系统修复软件 好吧&#xff0c;…

伦茨科技宣布ST17H6x芯片已通过Apple Find My「查找」认证

深圳市伦茨科技有限公司&#xff08;以下简称“伦茨科技”&#xff09;发布ST17H6x Soc平台。成为继Nordic之后全球第二家取得Apple Find My「查找」认证的芯片厂家&#xff0c;该平台提供可通过Apple Find My认证的Apple查找&#xff08;Find My&#xff09;功能集成解决方案。…

五、HotSpot细节实现

一、并发标记与三色标记 问题&#xff1a;三色标记到底发生在什么阶段&#xff0c;替代了什么。并发标记 1、并发标记( Concurrent Marking) 从 GC Root 开始对堆中对象进行可达性分析&#xff0c;递归扫描整个堆里的对象图&#xff0c;找出要回收的对象&#xff0c;这阶段耗…

Debian Linux安装配置ibus rime中文输入法

Linux安装配置Rime 安装 清除所有fcitx软件包 sudo apt purge fcitx*安装ibus和ibus-rime sudo apt install ibus ibus-rime启用输入法 找到输入法配置 启用ibus输入法 此时由于刚安装完毕ibus并没有启动 要么重启系统 要么输入下面的命令 ibus-daemon -drx找到ibus首选…

Python 模板引擎 Jinja2 的安装和使用

目录 一、概述 二、安装 Jinja2 三、使用 Jinja2 四、Jinja2的强大功能和优点 五、总结 一、概述 Jinja2 是 Python 中广泛使用的一种模板引擎&#xff0c;它具有灵活的语法、强大的控制结构、方便的 API&#xff0c;以及高效的渲染速度。通过使用 Jinja2&#xff0c;开发…

TQ2440开发板-按键驱动程序设计

目录 按键测试底板原理图核心板原理图使用轮询方式设计按键程序 按键测试底板原理图 TQ2440开发板有4个用户可编程按键&#xff0c;它们直接与CPU的GPIO相连&#xff0c;低电平触发中断&#xff0c;资源占用如下图所示&#xff1a; 核心板原理图 使用轮询方式设计按键程序 按…