小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
- 长轮询任务
每个长轮询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和本地磁盘中的文件内容进行比较,如果内存中的数据和磁盘中的数据不一致说明数据发生了变化,需要触发事件通知。