Nacos源码分析三、配置中心(2)

从NacosConfigService的构造方法里

this.worker = new ClientWorker(this.agent, this.configFilterChainManager, properties);

这行代码开始,看下ClientWorker的初始化做了什么:

public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager,
        final Properties properties) {
    // http代理
    this.agent = agent;
    // 过滤器
    this.configFilterChainManager = configFilterChainManager;
    
    // Initialize the timeout parameter
    // 初始化配置
    init(properties);

    this.executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setName("com.alibaba.nacos.client.Worker." + agent.getName());
            t.setDaemon(true);
            return t;
        }
    });

    // cpu核数的线程,用来做长轮询的,每次检查配置,如果LongPollingRunnable任务的配置缓存超过一定数量,默认3000个,就要去开启一个新任务去检查配置
    // Runtime.getRuntime().availableProcessors()获取cpu核数
    this.executorService = Executors
            .newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setName("com.alibaba.nacos.client.Worker.longPolling." + agent.getName());
                    t.setDaemon(true);
                    return t;
                }
            });

    // 10毫秒的任务,检查配置信息 LongPollingRunnable
    this.executor.scheduleWithFixedDelay(new Runnable() {
        @Override
        public void run() {
            try {
                checkConfigInfo();
            } catch (Throwable e) {
                LOGGER.error("[" + agent.getName() + "] [sub-check] rotate check error", e);
            }
        }
    }, 1L, 10L, TimeUnit.MILLISECONDS);
}

这里定义了两个线程池,executorService这里只定义了,还没放入线程,用来做长轮询的,核心线程数是CPU核数;executor每10毫秒执行一次checkConfigInfo方法。

我们看一下checkConfigInfo这个方法:

public void checkConfigInfo() {
    // Dispatch taskes.
    // 监听的数量
    int listenerSize = cacheMap.get().size();
    // Round up the longingTaskCount.
    // 监听数量/3000 向上取整
    int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
    if (longingTaskCount > currentLongingTaskCount) {
        for (int i = (int) currentLongingTaskCount; i < longingTaskCount; i++) {
            taskIdSet.add(i);
            // 循环3000次,建一个新的
            // LongPollingRunnable 长链接监听
            // 每个LongPollingRunnable默认可以负责3000个监听器的轮询
            executorService.execute(new LongPollingRunnable(i));
        }
    } else if (longingTaskCount < currentLongingTaskCount) {
        for (int i = longingTaskCount; i < (int) currentLongingTaskCount; i++) {
            taskIdSet.remove(i);
        }
    }
    currentLongingTaskCount = longingTaskCount;
}

ParamUtil.getPerTaskConfigSize()这个默认是3000。

这里的逻辑是这样的,根据监听器的数量建立长轮询任务,每3000个监听建一个任务并放入到executorService里。

监听器在cacheMap里,后面我们看addListener方法时会看到写入这个缓存的操作。

我们看一下LongPollingRunnable这个:

@Override
public void run() {
    
    List<CacheData> cacheDatas = new ArrayList<CacheData>();

    List<String> inInitializingCacheList = new ArrayList<String>();
    try {
        // check failover config
        for (CacheData cacheData : cacheMap.get().values()) {
            //属于当前长轮询任务的
            if (cacheData.getTaskId() == taskId) {
                cacheDatas.add(cacheData);
                try {
                    checkLocalConfig(cacheData);
                    //用本地配置
                    if (cacheData.isUseLocalConfigInfo()) {
                        //有改变的话会通知
                        cacheData.checkListenerMd5();
                    }
                } catch (Exception e) {
                    LOGGER.error("get local config info error", e);
                }
            }
        }

        //获取有变化的配置列表dataid+group,访问的url是/listener
        // check server config
        List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
        if (!CollectionUtils.isEmpty(changedGr
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值