当前位置: 首页 > news >正文

nacos获取服务实例流程

一、客户端获取服务实例流程(以dubbo为例)

1.dubbo元数据服务初始化需要订阅的服务列表

1.1.获取与当前服务相同分组和集群的NACOS的注册服务列表。

1.2 首先是从spring-cloud-common的通用注册中心中,使用组合注册客户端类获取服务,此组合会逐个调用注册客户端进行获取。

1.3 接下来向NACOS服务端获取服务列表。看到只返回了loveday这个服务提供者。

2.接下来获取服务的实例列表。

2.1 获取NacosDiscoverClient的实例接口。

2.2.注意,这里有一个hostreactor类,会定时从服务器更新最新的服务实例列表。

2.3 最终的获取服务实例列表,也是调用 NACOS服务端的HTTP接口

2.4 在获取实例时也会同时添加一个定时更新任务。定期从服务端拉取最新的服务列表到本地内存。此类的serviceInfoMap就是存服务对应的内存缓存实例列表。

public class HostReactor implements Closeable {
private final Map<String, ServiceInfo> serviceInfoMap;public synchronized ScheduledFuture<?> addTask(UpdateTask task) {return executor.schedule(task, DEFAULT_DELAY, TimeUnit.MILLISECONDS);}public ServiceInfo getServiceInfo(final String serviceName, final String clusters) {NAMING_LOGGER.debug("failover-mode: " + failoverReactor.isFailoverSwitch());String key = ServiceInfo.getKey(serviceName, clusters);if (failoverReactor.isFailoverSwitch()) {return failoverReactor.getService(key);}ServiceInfo serviceObj = getServiceInfo0(serviceName, clusters);if (null == serviceObj) {serviceObj = new ServiceInfo(serviceName, clusters);serviceInfoMap.put(serviceObj.getKey(), serviceObj);updatingMap.put(serviceName, new Object());updateServiceNow(serviceName, clusters);updatingMap.remove(serviceName);} else if (updatingMap.containsKey(serviceName)) {if (UPDATE_HOLD_INTERVAL > 0) {// hold a moment waiting for update finishsynchronized (serviceObj) {try {serviceObj.wait(UPDATE_HOLD_INTERVAL);} catch (InterruptedException e) {NAMING_LOGGER.error("[getServiceInfo] serviceName:" + serviceName + ", clusters:" + clusters, e);}}}}scheduleUpdateIfAbsent(serviceName, clusters);return serviceInfoMap.get(serviceObj.getKey());}public void scheduleUpdateIfAbsent(String serviceName, String clusters) {if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) != null) {return;}synchronized (futureMap) {if (futureMap.get(ServiceInfo.getKey(serviceName, clusters)) != null) {return;}ScheduledFuture<?> future = addTask(new UpdateTask(serviceName, clusters));futureMap.put(ServiceInfo.getKey(serviceName, clusters), future);}}}

2.5 最核心的更新实例任务类

public class UpdateTask implements Runnable {long lastRefTime = Long.MAX_VALUE;private final String clusters;private final String serviceName;/*** the fail situation. 1:can't connect to server 2:serviceInfo's hosts is empty*/private int failCount = 0;public UpdateTask(String serviceName, String clusters) {this.serviceName = serviceName;this.clusters = clusters;}private void incFailCount() {int limit = 6;if (failCount == limit) {return;}failCount++;}private void resetFailCount() {failCount = 0;}@Overridepublic void run() {long delayTime = DEFAULT_DELAY;try {ServiceInfo serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters));if (serviceObj == null) {updateService(serviceName, clusters);return;}if (serviceObj.getLastRefTime() <= lastRefTime) {updateService(serviceName, clusters);serviceObj = serviceInfoMap.get(ServiceInfo.getKey(serviceName, clusters));} else {// if serviceName already updated by push, we should not override it// since the push data may be different from pull through force pushrefreshOnly(serviceName, clusters);}lastRefTime = serviceObj.getLastRefTime();if (!notifier.isSubscribed(serviceName, clusters) && !futureMap.containsKey(ServiceInfo.getKey(serviceName, clusters))) {// abort the update taskNAMING_LOGGER.info("update task is stopped, service:" + serviceName + ", clusters:" + clusters);return;}if (CollectionUtils.isEmpty(serviceObj.getHosts())) {incFailCount();return;}delayTime = serviceObj.getCacheMillis();resetFailCount();} catch (Throwable e) {incFailCount();NAMING_LOGGER.warn("[NA] failed to update serviceName: " + serviceName, e);} finally {executor.schedule(this, Math.min(delayTime << failCount, DEFAULT_DELAY * 60), TimeUnit.MILLISECONDS);}}}

2.6 定时任务更新实例列表到内存完成。


http://www.mrgr.cn/news/16369.html

相关文章:

  • MP条件构造器之常用功能详解(or、and、exists、notExists)
  • Python 高级特效 - 生成器 ( Generator)
  • DAY59-图论-Bellman_ford
  • HCIP笔记12-交换(1)
  • cnocr 安装
  • Web开发 Ajax 2024/3/31
  • 【C++题解】1722 - 输出两位的巧数
  • 内存管理篇-16二级页表工作原理
  • 揭秘!糖尿病:从绝望到希望的治愈之路
  • Java高级Day34-流补充
  • 【自由能系列(初级)】第一性原理与自由能——从基础到系统做功的桥梁
  • 52基于SpringBoot+Vue+uniapp的旅游管理系统的的详细设计和实现(源码+lw+部署文档+讲解等)
  • 【STM32】BKP备份寄存器与RTC实时时钟
  • Stable Diffusion 必备插件推荐,菜鸟轻松成高手!
  • 海外融合CDN怎样优化?
  • C#学习笔记(二)安装开发环境、代码编译运行
  • Windows系统下不小心把输入法切换成了繁体怎么办
  • <数据集>车辆识别数据集<目标检测>
  • win10环境下gvim离线配置插件的一些补充
  • 强缓存和协商缓存