java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > NacosNamingService的作用

SpringCloud中NacosNamingService的作用详解

作者:阿孟呀

这篇文章主要介绍了SpringCloud中NacosNamingService的作用详解,NacosNamingService类完成服务实例注册,撤销与获取服务实例操作,NacosNamingService初始化采用单例模式,使用反射生成,需要的朋友可以参考下

NacosNamingService初始化

NacosNamingService类完成服务实例注册,撤销与获取服务实例操作。

生成方式:NacosNamingService初始化采用单例模式,使用反射生成。

NacosServiceRegistry bean初始化时,在构造中,根据nacos的属性配置文件,通过反射,初始化了NacosNamingService。

NacosServiceRegistry

public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {
		this.nacosDiscoveryProperties = nacosDiscoveryProperties;
		this.namingService = nacosDiscoveryProperties.namingServiceInstance();
	}
NacosDiscoveryProperties
public NamingService namingServiceInstance() {
 
		if (null != namingService) {
			return namingService;
		}
 
		try {
			namingService = NacosFactory.createNamingService(getNacosProperties());
		}
		catch (Exception e) {
			log.error("create naming service error!properties={},e=,", this, e);
			return null;
		}
		return namingService;
	}

NamingFactory

public static NamingService createNamingService(Properties properties) throws NacosException {
        try {
            Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
            Constructor constructor = driverImplClass.getConstructor(Properties.class);
            NamingService vendorImpl = (NamingService)constructor.newInstance(properties);
            return vendorImpl;
        } catch (Throwable e) {
            throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e);
        }
    }

NacosNamingService初始化过程

NacosNamingService初始化时,主要是进行了以下操作:

  1. 初始化命名空间,默认为public
  2. 初始化服务端地址.xxx:8848
  3. 初始化naocs 服务端两个webcontext,"/nacos//v1/ns"和"/nacos//v1/ns//instance"
  4. 初始化服务实例信息缓存目录,默认为用户目录下"/nacos/naming/public"
  5. 初始化日志
  6. 初始化事件分发器
  7. 初始化NamingProxy,像服务端发起请求的代理
  8. 初始化心跳信息,使用ScheduledThreadPoolExecutor初始化守护线程池,nacos默认5秒像服务端发起一次心跳,
  9. 初始化主机信息,默认不使用本地缓存。
public NacosNamingService(Properties properties) {
        init(properties);
    }
 
    private void init(Properties properties) {
        namespace = InitUtils.initNamespaceForNaming(properties);
        initServerAddr(properties);
        InitUtils.initWebRootContext();
        initCacheDir();
        initLogName(properties);
 
        eventDispatcher = new EventDispatcher();
        serverProxy = new NamingProxy(namespace, endpoint, serverList);
        serverProxy.setProperties(properties);
        beatReactor = new BeatReactor(serverProxy, initClientBeatThreadCount(properties));
        hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, isLoadCacheAtStart(properties), initPollingThreadCount(properties));
    }

NacosNamingService心跳启动

客户端向服务端发起请求时,会先通过定时任务启动心跳,默认心跳为5秒一次

public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
 
        if (instance.isEphemeral()) {
            BeatInfo beatInfo = new BeatInfo();
            beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));
            beatInfo.setIp(instance.getIp());
            beatInfo.setPort(instance.getPort());
            beatInfo.setCluster(instance.getClusterName());
            beatInfo.setWeight(instance.getWeight());
            beatInfo.setMetadata(instance.getMetadata());
            beatInfo.setScheduled(false);
            long instanceInterval = instance.getInstanceHeartBeatInterval();
            beatInfo.setPeriod(instanceInterval == 0 ? DEFAULT_HEART_BEAT_INTERVAL : instanceInterval);
               //启动心跳任务
            beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
        }
 
        serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
    }
public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
        NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo);
        String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort());
        BeatInfo existBeat = null;
        //fix #1733
        if ((existBeat = dom2Beat.remove(key)) != null) {
            existBeat.setStopped(true);
        }
        dom2Beat.put(key, beatInfo);//开启定时心跳任务
        executorService.schedule(new BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS);
        MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
    }

获取服务实例

@Override
    public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException {
 
        ServiceInfo serviceInfo;
        if (subscribe) {
            serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));//本地map获取
        } else {
            serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));//远程服务获取
        }
        List<Instance> list;
        if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
            return new ArrayList<Instance>();
        }
        return list;
    }

服务实例注销

@Override
    public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
        if (instance.isEphemeral()) {
            beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(), instance.getPort());
        }
        serverProxy.deregisterService(NamingUtils.getGroupedName(serviceName, groupName), instance);
    }

到此这篇关于SpringCloud中NacosNamingService的作用详解的文章就介绍到这了,更多相关NacosNamingService的作用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文