当前位置: 首页> 科技> 互联网 > 建e室内设计网官网图库_常德网站建设费用_搜索引擎优化seo优惠_网络营销策划推广

建e室内设计网官网图库_常德网站建设费用_搜索引擎优化seo优惠_网络营销策划推广

时间:2025/9/7 14:36:46来源:https://blog.csdn.net/m0_45164511/article/details/142726963 浏览次数:2次
建e室内设计网官网图库_常德网站建设费用_搜索引擎优化seo优惠_网络营销策划推广

Nacos1.4使用的都是http通信,nacos2.0之后改为使用grpc通信。

涉及到的核心方法:异步队列+写时复制(copyOnWrite)

1.客户端启动流程

1.验证服务实例

NacosNamingService(核心类)

2.用post调用http请求,注册实例(客户端向服务端发起请求,注册!)

/nacos/v1/ns/instance

(调用jdkHttpClient发起请求)

客户端启动流程:Auto自动装配->EventListener->bind->this.start->register(核心注册的方法)

 2.nacos服务端

添加服务实例:InstanceController#register,代码如下:

@CanDistro
@PostMapping
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String register(HttpServletRequest request) throws Exception {final String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);NamingUtils.checkServiceNameFormat(serviceName);final Instance instance = parseInstance(request);serviceManager.registerInstance(namespaceId, serviceName, instance);return "ok";
}

也就是将服务实例添加到服务端的Map中,该Map结构如下:(key-value结构)

Nacos服务注册表结构:Map<namespace, Map<group::serviceName, Service>>

服务拆分后,相同的服务类型放到一个group。比如说将订单服务拆分为支付服务、退货服务等。

接下来,服务端通过createEmptyService中的addInstance添加实例。

DistroConsistencyServiceImpl#onPut(key, value);->tasks.offer(Pair.with(datumKey, action));// 注册的实例丢到内存队列 ArrayBlockingQueue。集群的话会进行节点之间的同步。

DistroConsistencyServiceImpl阿里的分布式一致性协议的实现类Distro

 接下来,Notifier#run从队列中拿出实例-->onChange:真正通过这个线程的run方法来注册实例。调用handle方法注册实例,入口代码如下:

@Override
public void run() {Loggers.DISTRO.info("distro notifier started");for (; ; ) {// 死循环try {Pair<String, DataOperation> pair = tasks.take();// 拿出实例handle(pair);// 注册} catch (Throwable e) {Loggers.DISTRO.error("[NACOS-DISTRO] Error while handling notifying task", e);}}
}

之后会将服务实例注册到注册表中,AP架构的注册表为ephemeralInstances,代码如下:

@JsonIgnore
private Set<Instance> ephemeralInstances = new HashSet<>();

ephemeralInstances = toUpdateInstances;// 注册表 存放的实例的地方 是map中的内容

run是什么时候被执行的呢,run方法的类通过@PostConstruct注册成为一个bean,死循环会一直执行,用来检测是否有新实例出现。DistroConsistencyServiceImpl#

private volatile Notifier notifier = new Notifier();@PostConstruct
public void init() {GlobalExecutor.submitDistroNotifyTask(notifier);
}

总结

准实时注册

客户端发起http请求,进行注册

服务端将其放到内存队列中,然后后台线程(单线程)的run方法将实例进行注册,放到set集合中(双层Map中的set)

异步注册:满足高并发的需求,多个实例注册)业务操作都是基于内存的,set是在内存的

 为了防止多节点读写并发冲突,nacos采用写时复制技术

CopyOnWrite:写时复制,写的时候写到备份表,写完后,将表数据合并

读的时候读的是真正的表

复制的时候,存不存在原数据过大的问题?不会的,因为复制的仅仅是ephemeralInstances(set集合),复制到list中,之后的增删改都操作list!

list首先是从cache中拿的,然后会用实际的注册表进行更新健康状态!

 涉及到的代码如下:

Cluster#updateIps():

HashMap<String, Instance> oldIpMap = new HashMap<>(toUpdateInstances.size());// 复制出来的oldMapephemeralInstances = toUpdateInstances;// 替换注册表

写时复制的代码如下:

public void updateIps(List<Instance> ips, boolean ephemeral) {// ips新来的实例Set<Instance> toUpdateInstances = ephemeral ? ephemeralInstances : persistentInstances;HashMap<String, Instance> oldIpMap = new HashMap<>(toUpdateInstances.size());// 复制出来的oldMapfor (Instance ip : toUpdateInstances) {oldIpMap.put(ip.getDatumKey(), ip);// 放到oldIpMap}List<Instance> updatedIPs = updatedIps(ips, oldIpMap.values());// 仅仅拿到list,增删改 都在这个额副本中if (updatedIPs.size() > 0) {for (Instance ip : updatedIPs) {// 查看 新的实例是不是老实例,是不是配置变化Instance oldIP = oldIpMap.get(ip.getDatumKey());// do not update the ip validation status of updated ips// because the checker has the most precise result// Only when ip is not marked, don't we update the health status of IP:if (!ip.isMarked()) {ip.setHealthy(oldIP.isHealthy());}if (ip.isHealthy() != oldIP.isHealthy()) {// ip validation status updatedLoggers.EVT_LOG.info("{} {SYNC} IP-{} {}:{}@{}", getService().getName(),(ip.isHealthy() ? "ENABLED" : "DISABLED"), ip.getIp(), ip.getPort(), getName());}if (ip.getWeight() != oldIP.getWeight()) {// ip validation status updatedLoggers.EVT_LOG.info("{} {SYNC} {IP-UPDATED} {}->{}", getService().getName(), oldIP.toString(),ip.toString());}}}List<Instance> newIPs = subtract(ips, oldIpMap.values());// subtract删除实例的逻辑if (newIPs.size() > 0) {Loggers.EVT_LOG.info("{} {SYNC} {IP-NEW} cluster: {}, new ips size: {}, content: {}", getService().getName(),getName(), newIPs.size(), newIPs.toString());for (Instance ip : newIPs) {HealthCheckStatus.reset(ip);}}List<Instance> deadIPs = subtract(oldIpMap.values(), ips);if (deadIPs.size() > 0) {Loggers.EVT_LOG.info("{} {SYNC} {IP-DEAD} cluster: {}, dead ips size: {}, content: {}", getService().getName(),getName(), deadIPs.size(), deadIPs.toString());for (Instance ip : deadIPs) {HealthCheckStatus.remv(ip);}}toUpdateInstances = new HashSet<>(ips);if (ephemeral) {ephemeralInstances = toUpdateInstances;// 替换注册表} else {persistentInstances = toUpdateInstances;}}

关键字:建e室内设计网官网图库_常德网站建设费用_搜索引擎优化seo优惠_网络营销策划推广

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: