Nacos做为实用性服务项目中心,必定须要确保服务项目结点的可扩展性,因此Nacos是怎样同时实现软件产业的呢?

上面那个图,则表示Nacos软件产业的部署图。

Nacos软件产业组织工作基本原理

Nacos做为实用性服务项目中心的软件产业内部结构中,是一类无服务项目交互式化结点的内部结构设计,虽然没characterization结点,也没议会选举监督机制,因此为的是能同时实现接口卡,就须要减少交互式IP(VIP)。

Nacos的统计数据储存分成两部份

/data/program/nacos-1/data/config-data/${GROUP}

在Nacos的内部结构设计中,Mysql是一个服务项目中心统计数据仓库,且认为在Mysql中的统计数据是绝对正确的。 除此之外,Nacos在启动时会把Mysql中的统计数据写一份到本地磁盘。

这么内部结构设计的好处是可以提高性能,当客户端须要请求某个实用性项时,服务项目端会想Ian从磁盘中读取对应文件返回,而磁盘的读取效率要比统计数据库效率高。

当实用性发生变更时:

  1. Nacos会把变更的实用性保存到统计数据库,然后再写入本地文件。
  2. 接着发送一个HTTP请求,给到软件产业中的其他结点,其他结点收到事件后,从Mysql中dump刚刚写入的统计数据到本地文件中。

另外,NacosServer启动后,会同步启动一个定时任务,每隔6小时,会dump一次全量统计数据到本地文件

实用性变更同步入口

当实用性发生修改、删除、新增操作时,通过发布一个notifyConfigChange事件。

@PostMapping@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
public Boolean publishConfig(HttpServletRequest request, HttpServletResponse response,@RequestParam(value ="dataId") String dataId,@RequestParam(value ="group") String group,@RequestParam(value ="tenant", required = false, defaultValue = StringUtils.EMPTY) String tenant,@RequestParam(value ="content") String content,@RequestParam(value ="tag", required = false) String tag,@RequestParam(value ="appName", required = false) String appName,@RequestParam(value ="src_user", required = false) String srcUser,@RequestParam(value ="config_tags", required = false) String configTags,@RequestParam(value ="desc", required = false) String desc,@RequestParam(value ="use", required = false) String use,@RequestParam(value ="effect", required = false) String effect,@RequestParam(value ="type", required = false) String type,@RequestParam(value ="schema", required = false) String schema) throws NacosException {//省略..if(StringUtils.isBlank(betaIps)) {if(StringUtils.isBlank(tag)) {persistService.insertOrUpdate(srcIp, srcUser, configInfo, time, configAdvanceInfo, true);ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(false, dataId, group, tenant, time.getTime()));
        }else{persistService.insertOrUpdateTag(configInfo, tag, srcIp, srcUser, time, true);ConfigChangePublisher.notifyConfigChange(
                    new ConfigDataChangeEvent(false, dataId, group, tenant, tag, time.getTime()));
        }
    }//省略returntrue;
}

AsyncNotifyService

实用性统计数据变更事件,专门有一个监听器AsyncNotifyService,它会处理统计数据变更后的同步事件。

@AutowiredpublicAsyncNotifyService(ServerMemberManager memberManager){this.memberManager = memberManager;// Register ConfigDataChangeEvent to NotifyCenter.NotifyCenter.registerToPublisher(ConfigDataChangeEvent.class,NotifyCenter.ringBufferSize);// Register A Subscriber to subscribe ConfigDataChangeEvent.NotifyCenter.registerSubscriber(newSubscriber() {@OverridepublicvoidonEvent(Event event){// Generate ConfigDataChangeEvent concurrentlyif(eventinstanceofConfigDataChangeEvent) {
                ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event;longdumpTs = evt.lastModifiedTs;
                String dataId = evt.dataId;
                String group = evt.group;
                String tenant = evt.tenant;
                String tag = evt.tag;
                Collection ipList = memberManager.allMembers();//得到软件产业中的ip列表// 构建NotifySingleTask,并添加到队列中。Queue queue =newLinkedList();for(Member member : ipList) {//遍历软件产业中的每个结点queue.add(newNotifySingleTask(dataId, group, tenant, tag, dumpTs, member.getAddress(),
                            evt.isBeta));
                }//异步执行任务 AsyncTaskConfigExecutor.executeAsyncNotify(newAsyncTask(nacosAsyncRestTemplate, queue));
            }
        }@OverridepublicClass subscribeType() {returnConfigDataChangeEvent.class;
        }
    });
}

AsyncTask

@Overridepublicvoidrun(){
    executeAsyncInvoke();
}privatevoidexecuteAsyncInvoke(){while(!queue.isEmpty()) {//遍历队列中的统计数据,直到统计数据为空NotifySingleTask task = queue.poll();//获取taskString targetIp = task.getTargetIP();//获取目标ipif(memberManager.hasMember(targetIp)) {//如果软件产业中的ip列表包含目标ip// start the health check and there are ips that are not monitored, put them directly in the notification queue, otherwise notify//判断目标ip的健康状态booleanunHealthNeedDelay = memberManager.isUnHealth(targetIp);//if(unHealthNeedDelay) {//如果目标服务项目是非健康,则继续添加到队列中,延后再执行。// target ip is unhealthy, then put it in the notification listConfigTraceService.logNotifyEvent(task.getDataId(), task.getGroup(), task.getTenant(),null,
                        task.getLastModified(), InetUtils.getSelfIP(), ConfigTraceService.NOTIFY_EVENT_UNHEALTH,0, task.target);// get delay time and set fail count to the taskasyncTaskExecute(task);
            }else{//构建headerHeader header = Header.newInstance();
                header.addParam(NotifyService.NOTIFY_HEADER_LAST_MODIFIED, String.valueOf(task.getLastModified()));
                header.addParam(NotifyService.NOTIFY_HEADER_OP_HANDLE_IP, InetUtils.getSelfIP());if(task.isBeta) {
                    header.addParam("isBeta","true");
                }
                AuthHeaderUtil.addIdentityToHeader(header);//通过restTemplate发起远程调用,如果调用成功,则执行AsyncNotifyCallBack的回调方法restTemplate.get(task.url, header, Query.EMPTY, String.class,newAsyncNotifyCallBack(task));
            }
        }
    }
}

目标结点接收请求

统计数据同步的请求地址为,task.url=http://192.168.8.16:8848/nacos/v1/cs/communication/dataChange?dataId=log.yaml

1.本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2.分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3.不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4.本站提供的源码、模板、插件等其他资源,都不包含技术服务请大家谅解!
5.如有链接无法下载或失效,请联系管理员处理!
6.本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!