地址服务模式 nacos
官方有一个环境隔离实践的博文,在那篇博文中,阿里巴巴给出的例子是采用nginx
以及一个组件实现根据客户端的IP
信息路由到不同的nacos
集群中去
官方博文——阿里巴巴基于 Nacos 实现环境隔离的实践
源码解析 地址服务器添加nacos-server
节点
根据官方的介绍,只需要发起一个http
请求即可动态的添加nacos-server
节点
# Add IP to nacos cluster: curl -X POST ‘$ADDRESS_SERVER:8080/nacos/v1/as/nodes?ips=1.1.1.1:8848,2.2.2.2:8848,3.3.3.3:8848’
# Remove IP from nacos cluster:
curl -X DELETE ‘$ADDRESS_SERVER:8080/nacos/v1/as/nodes?ips=1.1.1.1:8848,2.2.2.2:8848,3.3.3.3:8848’
这里巧妙的复用了nacos
中服务发现的功能,将nacos-server
也作为一个服务注册到nacos-server
上,这样就可以实现动态的管理nacos
节点
节点添加、删除源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 @RequestMapping (value = "" , method = RequestMethod.POST)public ResponseEntity postCluster (@RequestParam(required = false ) String product, @RequestParam (required = false ) String cluster, @RequestParam (name = "ips" ) String ips) { String productName = addressServerGeneratorManager.generateProductName(product); String clusterName = addressServerManager.getDefaultClusterNameIfEmpty(cluster); String rawProductName = addressServerManager.getRawProductName(product); String rawClusterName = addressServerManager.getRawClusterName(cluster); Loggers.addressLogger.info("put cluster node,the cluster name is " + cluster + "; the product name=" + product + "; the ip list=" + ips); ResponseEntity responseEntity; try { String serviceName = addressServerGeneratorManager.generateNacosServiceName(productName); Cluster clusterObj = new Cluster(); clusterObj.setName(clusterName); clusterObj.setHealthChecker(new AbstractHealthChecker.None()); serviceManager.createServiceIfAbsent(Constants.DEFAULT_NAMESPACE_ID, serviceName, false , clusterObj); String[] ipArray = addressServerManager.splitIps(ips); String checkResult = AddressServerParamCheckUtil.checkIps(ipArray); if (AddressServerParamCheckUtil.CHECK_OK.equals(checkResult)) { List<Instance> instanceList = addressServerGeneratorManager.generateInstancesByIps(serviceName, rawProductName, clusterName, ipArray); for (Instance instance : instanceList) { serviceManager.registerInstance(Constants.DEFAULT_NAMESPACE_ID, serviceName, instance); } responseEntity = ResponseEntity.ok("product=" + rawProductName + ",cluster=" + rawClusterName + "; put success with size=" + instanceList.size()); } else { responseEntity = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(checkResult); } } catch (Exception e) { responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } return responseEntity; }
通过上面这种操作以及nacos
的服务数据同步,就可以将新增的nacos-server
节点同步到所有的nacos-server
节点上,并且依托nacos
自带的健康检查功能,自动的判断不健康的nacos-server
实例信息,这样,nacos-client
只需要通过向地址服务器请求nacos-server
这个服务,就可以自动的得知nacos-server
节点变化的动态感知
客户端请求nacos-server
服务信息
请求源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @RequestMapping (value = "/{product}/{cluster}" , method = RequestMethod.GET)public ResponseEntity getCluster (@PathVariable String product, @PathVariable String cluster) { String productName = addressServerBuilderManager.generateProductName(product); String serviceName = addressServerBuilderManager.generateNacosServiceName(productName); Service service = serviceManager.getService(Constants.DEFAULT_NAMESPACE_ID, serviceName); if (service == null ) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + product + " not found." ); } if (!service.getClusterMap().containsKey(cluster)) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("product=" + product + ",cluster=" + cluster + " not found." ); } Cluster clusterObj = service.getClusterMap().get(cluster); return ResponseEntity.status(HttpStatus.OK).body(addressServerBuilderManager.generateResponseIps(clusterObj.allIPs(false ))); }
这里的实现非常简单,客户端仅仅需要像请求服务一样去请求nacos-server
服务即可