我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Nacos服务发现并发启动scheduleUpdate定时任务的流程分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Nacos服务发现并发启动scheduleUpdate定时任务的流程分析

一、前言

博主今天复习Nacos源码的时候,发现了一个算是有意思的细节点,这里分享一下。

二、服务发现“懒加载”机制

当nacos客户端运⾏起来之后,它只是去做服务注册、配置获取等操作;并不会立即去请求服务信息;当第一次请求时候,才会去获取服务,即懒加载机制

1、服务发现流程

Client端做服务发现时,无论是否能从本地缓存中获取到服务实例信息,都会启动一个定时任务(每秒做一次服务实例信息的更新)。然而由于可能多个请求同时要做服务发现,这样总不能每一次做服务发现时都去启动一个定时任务做服务实例信息更新吧。所以肯定要有一个机制去确保针对某一个Cluster下的Service,当前Client只会启动一个定时任务。

2、HostReactor#scheduleUpdateIfAbsent()

HostReactor#scheduleUpdateIfAbsent()方法负责启动做服务实例信息更新的定时任务。
从方法名也能看出来:是当定时任务不存在时,才会启动一个定时任务。

private final Map<String, ScheduledFuture<?>> futureMap = new HashMap<String, ScheduledFuture<?>>();

public void scheduleUpdateIfAbsent(String serviceName, String clusters) {
    if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) != null) {
        return;
    }
    
    synchronized (futureMap) {
        if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) != null) {
            return;
        }
        
        ScheduledFuture<?> future = addTask(new UpdateTask(serviceName, clusters));
        futureMap.put(ServiceInfo.getKey(serviceName, clusters), future);
    }
}

看一下这个代码逻辑:

  • 为了防止一个实例开启多个这种定时任务,会用一个Map来去重,针对这个Map的数据添加会采用一个类似双重检查锁的机制,确保Map添加数据的线程安全性。
  • 如果futureMap中已经有了当前服务,则方法直接返回。
  • 这一步是为了减少不必要的同步操作。
  • 否则,对futureMap对象加synchronized锁;同步代码块需要再进一步判断futureMap不为空。
  • 因为在多线程并发场景下,可能多个线程判断futureMap中都没有当前服务,都进入到同步代码块,一个线程进入同步代码块,将当前服务添加到futureMap中。
  • 其他线程获取到锁之后再进入到同步代码块,再次判断futureMap中是否含有当前服务,如果含有,则方法直接返回。
  • 假如同步代码中不判空,会重复执行将当前服务添加到futureMap中的操作。

既然是DCL的变种版,为了futureMap没有被volatile关键字修饰,不会有指令重排序的问题吗?

  • 并不会,futureMap.put()是Map的添加数据操作,和对象初始化是两种场景。

3、DCL

Double check Lock确保类单例的代码如下:

public class DoubleCheckLazySingleton {

    private volatile static DoubleCheckLazySingleton singleton;

    private DoubleCheckLazySingleton() {
    }

    public DoubleCheckLazySingleton getSingleton() {
        if (singleton == null) {
            synchronized (this) {
                //只有在singleton为null的时候才创建实例
                if (singleton == null) {
                    singleton = new DoubleCheckLazySingleton();
                }
            }
        }
        return singleton;
    }
}

到此这篇关于Nacos服务发现并发启动scheduleUpdate定时任务的文章就介绍到这了,更多相关Nacos服务发现内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Nacos服务发现并发启动scheduleUpdate定时任务的流程分析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Nacos服务发现并发启动scheduleUpdate定时任务的流程分析

这篇文章主要介绍了Nacos服务发现并发启动scheduleUpdate定时任务,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-02-23

python多线程多并发启动appium服务的实现

本文介绍了使用Python多线程启动Appium服务的方法。通过创建进程池并使用apply_async(),可以同时启动多个Appium服务,从而并行化测试执行、优化资源利用并提高灵活性。需要注意系统资源充足、处理服务间资源冲突以及使用同步机制协调资源访问。
python多线程多并发启动appium服务的实现
2024-04-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录