【Spring Cloud Alibaba 系列】Nacos 长轮询任务

598 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

  • 长轮询任务

每个长轮询LongPollingRunnable任务处理3000个监听配置集,如果超过3000个,则需要启动多个LongPollingRunnable去执行。

LongPollingRunnable.run

LongPollingRunnable是一个线程,找到LongPollingRunnable方法

  • 通过checkLocalConfig方法检查本地配置。
  • 执行checkUpdateDataIds方法和在服务器建立长轮询机制,从服务端获取发生修改的数据
  • 遍历修改数据集合changedGroupKeys,调用getServerConfig方法,根据dataId、Group、

Tenant去服务器读取对应的配置信息并保存到本地文件。

public void run(){
List<CacheData> cacheDatas=new ArrayList<CacheData>();
List<String> inInitializingCacheList = new ArrayList<String>();
 try{
 	for(CacheData cacheData:cacheMap.get().values()){
 		if(cahceData.getTaskId() == taskId){
 		cahceDatas.add(cacheData);
 		}
 		try{
 			checkLocalConfig(cacheData);
 			if(cacheData.isUseLocalConfigInfo()){
 			cahceData.checkListenerMd5();
 			}
 		}catch(Exception e){
 		LOGGER.error("get local config info error",e);
 		}
 	}
 }
  List<String> changeGroupKeys = checkUpdateDataIds(cacheDatas,inInitalizingCacheList);
  for(String groupKey:changedGroupKeys){
  String[] keysGroupKey.parseKey(groupKey);
  String dataId = key[0];
  String group = key[1];
  String tenant = null;
  if(key.length == 3){
  tenant = key[2];
  }
  try{
  	String content = getServerClient(dataId,group,tenant,3000L);
  	CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId,group,tenant));
  	cache.setContent(content);
  	LOGGER.info("[{}][data-received] dataId = {},group={},tenant={},md5={},content={}",agent.getName(),dataId,group,tenant);
  	LOGGER.error(message,ice);
  	
  }
  
  }
  for(CacheData cacheData:cacheDatas){
  if(!cacheData.isInitializing() || inInitializingCacheList.contais(GroupKey.getKeyTenant(cacheData.dataId,cahceData.group,cacheData.tenant))){
  cacheData.checkListenerMd5();
  cacheData.setInitializing(false);
    }
  }
    inInitializingCahceList.clear();
    //继续定时执行当前线程
    executorService.execute(this);
}catch(Throwable e){
    LOGGER.error("longPolling error:",e);
    executorService.schedule(this,taskPenaltyTime,TimeUnit.MILLISECONDS);
}

根据taskId对cacheMap进行数据分割,再比较本地配置文件的数据是否存在变更,如果有修改,则直接触发通知。注意的是在${user}/nacos/config/目录下缓存一份服务端的配置信息,checkLocalConfig和本地磁盘中的文件内容进行比较,如果内存中的数据和磁盘中的数据不一致说明数据发生了变化,需要触发事件通知。