[Nacos] Nacos Server处理注销请求 (七)

文章目录

      • 1.InstanceController.deregister()
      • 1.1 从请求中获取要操作的instance
      • 1.2 删除instance

1.InstanceController.deregister()

 

1、 从请求中获取要操作的instance;
2、 从注册表中获取service;
3、 从获取的service中删除instance;

1.1 从请求中获取要操作的instance
    private Instance getIpAddress(HttpServletRequest request) {
   
     
        // 从请求中获取各种属性
        final String ip = WebUtils.required(request, "ip");
        final String port = WebUtils.required(request, "port");
        String cluster = WebUtils.optional(request, CommonParams.CLUSTER_NAME, StringUtils.EMPTY);
        if (StringUtils.isBlank(cluster)) {
   
     
            cluster = WebUtils.optional(request, "cluster", UtilsAndCommons.DEFAULT_CLUSTER_NAME);
        }
        String enabledString = WebUtils.optional(request, "enabled", StringUtils.EMPTY);
        boolean enabled;
        if (StringUtils.isBlank(enabledString)) {
   
     
            enabled = BooleanUtils.toBoolean(WebUtils.optional(request, "enable", "true"));
        } else {
   
     
            enabled = BooleanUtils.toBoolean(enabledString);
        }

        boolean ephemeral = BooleanUtils.toBoolean(
                WebUtils.optional(request, "ephemeral", String.valueOf(switchDomain.isDefaultInstanceEphemeral())));

        String weight = WebUtils.optional(request, "weight", "1");
        boolean healthy = BooleanUtils.toBoolean(WebUtils.optional(request, "healthy", "true"));

        // 使用获取到的属性值装配一个instance
        Instance instance = new Instance();
        instance.setPort(Integer.parseInt(port));
        instance.setIp(ip);
        instance.setWeight(Double.parseDouble(weight));
        instance.setClusterName(cluster);
        instance.setHealthy(healthy);
        instance.setEnabled(enabled);
        instance.setEphemeral(ephemeral);

        return instance;
    }

1、 从请求中获取各种属性,ip,port,cluster,ephemeral是否为临时实例,weight权重;
2、 使用获取到的属性值装配一个instance;
 

1.2 删除instance

ServiceManager#removeInstance()

    public void removeInstance(String namespaceId, String serviceName, boolean ephemeral, Instance... ips)
            throws NacosException {
   
     
        // 从注册表获取当前service
        Service service = getService(namespaceId, serviceName);

        synchronized (service) {
   
     
            // 删除
            removeInstance(namespaceId, serviceName, ephemeral, service, ips);
        }
    }

 

 

 

ServiceManager#substractIpAddresses() -> Service#updateIpAddresses(): 用于修改当前instance列表, 修改分为添加和删除操作, 之前的Nacos Server处理注册请求的时候, 有这个添加的操作分析, 而现在是删除操作。

 

    public List<Instance> updateIpAddresses(Service service, String action, boolean ephemeral, Instance... ips)
            throws NacosException {
   
     

        // 从其它nacos获取当前服务数据(临时实例数据)
        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());
        Set<String> currentInstanceIds = Sets.newHashSet();

        // 遍历注册表中获取到的实例
        for (Instance instance : currentIPs) {
   
     
            // 将当前遍历的instance写入到map,key为ip:port,value为instance
            currentInstances.put(instance.toIpAddr(), instance);
            // 将当前遍历的instanceId写入到一个set
            currentInstanceIds.add(instance.getInstanceId());
        }

        Map<String, Instance> instanceMap;
        if (datum != null) {
   
     
            // 将注册表中主机的instance数据替换掉外来的相同主机的instance数据
            instanceMap = setValid(((Instances) datum.value).getInstanceList(), currentInstances);
        } else {
   
     
            instanceMap = new HashMap<>(ips.length);
        }

        for (Instance instance : ips) {
   
     
            // 若当前service中不包含当前要注册的instance所属cluster,则创建一个
            if (!service.getClusterMap().containsKey(instance.getClusterName())) {
   
     
                Cluster cluster = new Cluster(instance.getClusterName(), service);
                // 初始化cluster的健康检测任务
                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());
            }

            // 若当前操作为清除操作,则将当前instance从instanceMap中清除,
            // 否则就是添加操作,即将当前instance添加到instanceMap中
            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: " + JacksonUtils
                            .toJson(instanceMap.values()));
        }

        return new ArrayList<>(instanceMap.values());
    }

1、 从其它nacos获取当前服务数据(临时实例数据);
2、 获取本地注册表中当前服务的所有临时实例;
3、 遍历注册表中获取到的实例,将当前遍历的instance写入到map,将当前遍历的instanceId写入到一个set;
4、 将注册表中主机的instance数据替换掉外来的相同主机的instance数据;
5、 若当前service中不包含当前要注册的instance所属cluster,则创建一个,初始化cluster的健康检查任务;
6、 若当前操作为清除操作,则将当前instance从instanceMap中清除;
7、 返回修改后的instance列表;

ServiceManager#setValid(): 将注册表中主机的instance数据替换掉外来的相同主机的instance数据

 

1、 遍历外来的instance集合;
2、 从注册表包含的instance中若可以找到当前遍历的instance,则将注册表中该主机的instance数据替换掉外来的数据;
3、 返回列表;

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: