public String reqAPI(String api, Map<String, String> params, List<String> servers, String method){ params.put(CommonParams.NAMESPACE_ID, getNamespaceId()); if (CollectionUtils.isEmpty(servers) && StringUtils.isEmpty(nacosDomain)) { thrownew IllegalArgumentException("no server available"); } Exception exception = new Exception(); if (servers != null && !servers.isEmpty()) { Random random = new Random(System.currentTimeMillis()); int index = random.nextInt(servers.size()); for (int i = 0; i < servers.size(); i++) { String server = servers.get(index); try { return callServer(api, params, server, method); } catch (NacosException e) { exception = e; NAMING_LOGGER.error("request {} failed.", server, e); } catch (Exception e) { exception = e; NAMING_LOGGER.error("request {} failed.", server, e); } index = (index + 1) % servers.size(); } thrownew IllegalStateException("failed to req API:" + api + " after all servers(" + servers + ") tried: " + exception.getMessage()); } for (int i = 0; i < UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT; i++) { try { return callServer(api, params, nacosDomain); } catch (Exception e) { exception = e; NAMING_LOGGER.error("[NA] req api:" + api + " failed, server(" + nacosDomain, e); } } thrownew IllegalStateException("failed to req API:/api/" + api + " after all servers(" + servers + ") tried: " + exception.getMessage()); }
可以看到如果Nacos Server端的地址列表为空,那么Nacos Server应该是单机模式部署的,因此直接到最后一个for循环,循环次数为默认设置的Http请求可重试次数;如果Nacos Serve是已集群模式部署的话,那么会采用随机策略选择一个Nacos Server Addr作为进行Instance注册的Http请求地址;如果请求失败的话则再次重新选取一个Nacos Server
Datum datum = consistencyService.get(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), ephemeral));
Map<String, Instance> oldInstanceMap = new HashMap<>(16); List<Instance> currentIPs = service.allIPs(ephemeral); Map<String, Instance> map = new ConcurrentHashMap<>(currentIPs.size());
for (Instance instance : currentIPs) { map.put(instance.toIPAddr(), instance); } if (datum != null) { oldInstanceMap = setValid(((Instances) datum.value).getInstanceList(), map); }
// use HashMap for deep copy: HashMap<String, Instance> instanceMap = new HashMap<>(oldInstanceMap.size()); instanceMap.putAll(oldInstanceMap);
for (Instance instance : ips) { if (!service.getClusterMap().containsKey(instance.getClusterName())) { Cluster cluster = new Cluster(instance.getClusterName()); cluster.setService(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 { instanceMap.put(instance.getDatumKey(), instance); }
}
if (instanceMap.size() <= 0 && UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD.equals(action)) { thrownew IllegalArgumentException("ip list can not be empty, service: " + service.getName() + ", ip list: " + JSON.toJSONString(instanceMap.values())); }