In-depth source code analysis of NacosConfigService and ClientWorker

Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

NacosConfigService

NacosConfigService constructor:

  • Initialize a HttpAgent, use the decorator pattern, the working class is ServerHttpAgent, MetricsHttpAgent internal also calls the ServerHttpAgent method, increases the monitoring statistics.
  • ClientWorker is a client work class. The agent parameter is passed to the ClientWorker to do some remote work with the agent.
public NacosConfigService(Properties properties) throws NacosException{
	String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
	if(StringUtils.isBlank(encodeTmp)){
	encode=Constants.ENCODE;
	}else{
	encode = encodeTmp.trim();
	}
	initNamespace(properties);
	agent = new MeticsHttpAgent(new ServerHttpAgent(properties));
	agent.start();
	worker = new ClientWorker(agent,configFilterChainManager,properties);
}
Copy the code
ClientWorker

ClientWorker constructor:

  • Build two scheduled thread pools and start a scheduled task.
  • The first executor thread pool has only one core thread that executes the checkConfigInfo() method every 10ms.

The second thread pool executorService is only initialized to implement the timed long polling function on the client.

public ClientWorker(final HttpAgent aagent,final ConfigFilterChainManager configFilterChainManager,final Properties properties){
    this.agent=agent;
    this.configFilterChainManager=configFilterChainManager;
    init(properties);
    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);
            returnt; }}); excutorService= Excutors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(),new ThreadFactory(){
        @Override
        public Thread newThread(Runnable r){
           Thread t =  new Thread(r);
            t.setName("com.alibaba.nacos.client.longPilling."+agent.getName());
            t.setDaemon(true);
            returnt; }}); executor.scheduleWithFixedDelay(new Runnable(){
        @Override
        public void run(a){
            try{
                checkConfigInfo();
            }catch(Throwable e){
                LOGGER.error("["+agent.getName()+"][sub-check] rotate check error",e); }}}); }Copy the code
ClientWorker.checkConfigInfo

Then go deep into the ClientWorker constructor, through executor. ScheduleWithFixedDelay start a every 10 s timing to perform a task, call checkConfigInfo method, this method mainly check whether configuration changes, A thread pool scheduled with executorService.

public void checkConfigInfo(a){
    int listenerSize = cacheMap.get().size();
    int longingTasjCount=(int)Math.ceil(listenerSize/ParamUtil.getPerTaskConfigSize());
	if(longTaskCount> currentLongingTaskCount){
        for(int i=(int)currentLongingTaskCount; i<longingTaskCount; i++){ executorService.execute(newLongPollingRunnable(i)); } currentLongingTaskCount = longingTaskCount; }}Copy the code
  • cacheMap:

AtomicReference<Map<String,CacheData>> cacheMap is used to store the cache collection that listens for changes. The key is based on the dataId

/group/tenant(tenant) Spliced value. Value is the content of the corresponding configuration file stored in the Nacos server.