nacos源码解析<1>

之前我们看了微服务中用nacos做注册中心,openFeing+ribbon 发起调用 ,feign 底层依赖ribbon
从注册中心吧服务列表拉取到本地, 然后在本地实现负载均衡 发起请求

在这里插入图片描述

我们知道nacos分client,service,服务注册就是我们服务在启动的时候吧我们的服务注册上去
心跳机制就是检测我们一个client下线了,我们的微服务怎么做到的感知 通过心跳机制让我们nacos的server知道服务还存活
服务下线之后就不会再发送心跳了。server就会认为你已经挂了,就会吧状态设置为down

在这里插入图片描述

Nacos  的核心功能点

注册
心跳
健康检查
服务发现
服务同步
包括集群中间数据同步
我们吧服务注册在服务上去的时候 会导入nacos的client的jar, 然后在yaml中进行配置 
然后服务启动就吧自己 注册在nacos服务上去了

在这里插入图片描述

NacosDiscoveryAutoConfiguration  他的这个自动装配类 就@Bean注入了者三个
NacosServiceRegistry
NacosRegistration
NacosAutoServiceRegistration
然后我们看这个类  的父类

在这里插入图片描述

#####看这里
	@Deprecated
	public void bind(WebServerInitializedEvent event) {
		ApplicationContext context = event.getApplicationContext();
		if (context instanceof ConfigurableWebServerApplicationContext) {
			if ("management".equals(((ConfigurableWebServerApplicationContext) context)
					.getServerNamespace())) {
				return;
			}
		}
		this.port.compareAndSet(0, event.getWebServer().getPort());
		this.start();
	}

###########  然后看这个register()
register();

namingService.registerInstance(serviceId, instance);
####### 这里就实际上调用nacos的api 吧我们的实例注册上去了
    public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {

        NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}",
            namespaceId, serviceName, instance);

        final Map<String, String> params = new HashMap<String, String>(9);
        params.put(CommonParams.NAMESPACE_ID, namespaceId);
        params.put(CommonParams.SERVICE_NAME, serviceName);
        params.put(CommonParams.GROUP_NAME, groupName);
        params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
        params.put("ip", instance.getIp());
        params.put("port", String.valueOf(instance.getPort()));
        params.put("weight", String.valueOf(instance.getWeight()));
        params.put("enable", String.valueOf(instance.isEnabled()));
        params.put("healthy", String.valueOf(instance.isHealthy()));
        params.put("ephemeral", String.valueOf(instance.isEphemeral()));
        params.put("metadata", JSON.toJSONString(instance.getMetadata()));

        reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.POST);

    }
上面说的是client客户端源码  下来我们说下服务端的源码
我们现在要看客户端传过来的Instence是怎么注册的
#####这个是服务端源码  当接受一个服务注册的请求的时候 我们服务端会怎么去做
    public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {

        createEmptyService(namespaceId, serviceName, instance.isEphemeral());

        Service service = getService(namespaceId, serviceName);

        if (service == null) {
            throw new NacosException(NacosException.INVALID_PARAM,
                    "service not found, namespace: " + namespaceId + ", service: " + serviceName);
        }

        addInstance(namespaceId, serviceName, instance.isEphemeral(), instance);
    }
#######  看这个
createEmptyService(namespaceId, serviceName, instance.isEphemeral());
###########
这是nacos中服务的节点的信息内存结构 双层map存储注册信息
/**
* Map(namespace, Map(group::serviceName, Service)).
*/
private final Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();
这里put了一个新的内存结构
    public void putService(Service service) {
        if (!serviceMap.containsKey(service.getNamespaceId())) {
            synchronized (putServiceLock) {
                if (!serviceMap.containsKey(service.getNamespaceId())) {
                    serviceMap.put(service.getNamespaceId(), new ConcurrentSkipListMap<>());
                }
            }
        }
        serviceMap.get(service.getNamespaceId()).put(service.getName(), service);
    }

在这里插入图片描述

紧接着我们看这里的init  意味着初始化要做的操作	
 // 初始化要做检查任务 这个是做心跳检查的(客户端定时周期发心跳)
 service.init(); ----->>> HealthCheckReactor.scheduleCheck(clientBeatCheckTask);
 ------> GlobalExecutor.scheduleNamingHealth(task, 5000, 5000, TimeUnit.MILLISECONDS)
 (定时任务)
 然后我们看线程的run方法 就是拿到所有的服务节点 如果超过一定时间 服务端还没有发送心跳的话 我就给设置为false
 

在这里插入图片描述

之后再看 就是怎么把我们的服务实例注册上去的
   public void addInstance(String namespaceId, String serviceName, boolean ephemeral, Instance... ips)
            throws NacosException {

        String key = KeyBuilder.buildInstanceListKey(namespaceId, serviceName, ephemeral);
        //  此时关于整体的服务信息 还没有加入节点
        Service service = getService(namespaceId, serviceName);

        synchronized (service) {
            // 基于这个service 找到所有的  instanceList  包括此时新加入的
            List<Instance> instanceList = addIpAddresses(service, ephemeral, ips);
            Instances instances = new Instances();
            instances.setInstanceList(instanceList);

            consistencyService.put(key, instances);
        }
        然后看这个

#####3
  这里
    public void put(String key, Record value) throws NacosException {
            onPut(key, value);
        distroProtocol.sync(new DistroKey(key, KeyBuilder.INSTANCE_LIST_KEY_PREFIX), DataOperation.CHANGE,
                globalConfig.getTaskDispatchPeriod() / 2);
    }
这里的onput 实际上就是吧我们的instence实例节点 存储在了dataStore.put(key, datum);
  // datumKey 操作
tasks.offer(Pair.with(datumKey, action)); // 然后吧这些instence实例封装成了Pair对象 放在了
        private BlockingQueue<Pair<String, DataOperation>> tasks = new ArrayBlockingQueue<>(1024 * 1024);

阻塞队列中 

这其实他的注册逻辑就完事了。我们到底是没有看到怎么insert到他之前构建的双层map中
这个可能就是阻塞队列需要下一步的消费
#  分临时节点的注册和持久节点的注册 一般都是true 为临时节点
private ConsistencyService mapConsistencyService(String key) {
        return KeyBuilder.matchEphemeralKey(key) ? ephemeralConsistencyService : persistentConsistencyService;
    }

在这里插入图片描述
在这里插入图片描述

阻塞队列  最终把我们客户端传过来的instence 封装成pare对象放在阻塞队列中 注册逻辑结束了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值