Spring Cloud 2.2.2 源码之五十五nacos服务端处理注册实例请求三

Service模型大致结构

在这里插入图片描述

ServiceManager的addIpAddresses

上篇说到增加实例这里,看看他是怎么添加的:
在这里插入图片描述

ServiceManager的addIpAddresses

做的是一个添加的操作。

public static final String UPDATE_INSTANCE_ACTION_ADD = "add";

    public List<Instance> addIpAddresses(Service service, boolean ephemeral, Instance... ips) throws NacosException {
        return updateIpAddresses(service, UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD, ephemeral, ips);
    }

updateIpAddresses更新服务实例

这里面还做了挺多的事,先是获取老的数据(持久的或者临时的),从一致性服务里获取,因为这个数据是要同步更新的,所以要拿出来及时更新,然后获取服务实例(持久的或者临时的),用他们来更新的老的数据,然后遍历新增的实例,如果没有集群的话先创建集群,并初始化集群,会开启心跳检查,最后根据是添加还是删除实例来更新老的实例映射,最后封装成集合返回最新的实例集合。

    public List<Instance> updateIpAddresses(Service service, String action, boolean ephemeral, Instance... ips) throws NacosException {
        //获取老的实例集合数据
        Datum datum = consistencyService.get(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), ephemeral));
        //获取集群中所有相关的实例集合,临时的或者是永久的
        List<Instance> currentIPs = service.allIPs(ephemeral);
        Map<String, Instance> currentInstances = new HashMap<>(currentIPs.size());//IP端口和实例的映射
        Set<String> currentInstanceIds = Sets.newHashSet();//实例ID集合
        //放入对应的集合里
        for (Instance instance : currentIPs) {
            currentInstances.put(instance.toIPAddr(), instance);
            currentInstanceIds.add(instance.getInstanceId());
        }
        //更新后的老的实例集合
        Map<String, Instance> instanceMap;
        if (datum != null) {//根据当前服务实例的健康标志和心跳时间,来更新老的实例集合数据
            instanceMap = setValid(((Instances) datum.value).getInstanceList(), currentInstances);
        } else {//重新创建一个
            instanceMap = new HashMap<>(ips.length);
        }

        for (Instance instance : ips) {//遍历新的实例
            if (!service.getClusterMap().containsKey(instance.getClusterName())) {//不存在就创建服务实例集群
                Cluster cluster = new Cluster(instance.getClusterName(), service);
                cluster.init();//初始化,开启集群心跳检查
                service.getClusterMap().put(instance.getClusterName(), cluster);//添加服务实例集群
                Loggers.SRV_LOG.warn("cluster: {} not found, ip: {}, will create new cluster with default configuration.",
                    instance.getClusterName(), instance.toJSON());
            }
            //删除操作的话就删除老的实例集合的数据
            if (UtilsAndCommons.UPDATE_INSTANCE_ACTION_REMOVE.equals(action)) {
                instanceMap.remove(instance.getDatumKey());
            } else {//否则添加
                instance.setInstanceId(instance.generateInstanceId(currentInstanceIds));
                instanceMap.put(instance.getDatumKey(), instance);
            }

        }

        if (instanceMap.size() <= 0 && UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD.equals(action)) {
            throw new IllegalArgumentException("ip list can not be empty, service: " + service.getName() + ", ip list: "
                + JSON.toJSONString(instanceMap.values()));
        }
        //返回总的实例集合
        return new ArrayList<>(instanceMap.values());
    }

Service的allIPs获取集群中的实例集合

遍历集群,获取集群里的实例集合,临时的或者是永久的。

    public List<Instance> allIPs(boolean ephemeral) {
        List<Instance> allIPs = new ArrayList<>();
        for (Map.Entry<String, Cluster> entry : clusterMap.entrySet()) {
            allIPs.addAll(entry.getValue().allIPs(ephemeral));
        }

        return allIPs;
    }

ServiceManager的setValid更新老的实例集合

其实就是用服务集群中获取的实例集合去更新老的实例集合,健康状态和心跳时间。

    private Map<String, Instance> setValid(List<Instance> oldInstances, Map<String, Instance> map) {

        Map<String, Instance> instanceMap = new HashMap<>(oldInstances.size());
        for (Instance instance : oldInstances) {//遍历老的实例集合,如果新的实例存在的话就更新
            Instance instance1 = map.get(instance.toIPAddr());//获取对应新的实例
            if (instance1 != null) {//存在就更新
                instance.setHealthy(instance1.isHealthy());
                instance.setLastBeat(instance1.getLastBeat());
            }
            instanceMap.put(instance.getDatumKey(), instance);//放入映射
        }
        return instanceMap;
    }

Cluster的init集群初始化

即是开启一个心跳检查的任务,具体任务后面说。

    public void init() {
        if (inited) {
            return;
        }
        checkTask = new HealthCheckTask(this);

        HealthCheckReactor.scheduleCheck(checkTask);
        inited = true;
    }

DelegateConsistencyServiceImpl的put

实例创建好了,返回了新的实例集合,这个时候就去放到一致性服务里了:
在这里插入图片描述
会根据传进来的是临时的还是永久的key来选择对应的服务。
在这里插入图片描述

下篇继续将对应的服务怎么处理实例集合。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章