手写Nacos基本原理——服务注册 配置管理

手写Nacos基本原理

  • 一、背景介绍
  • 二、 思路方案
  • 三、过程
    • nacosService代码
      • pom文件
      • 配置文件
      • 具体类
    • nacosSDK代码
      • pom文件
      • 配置类
      • 具体类
    • serviceA代码
      • pom文件
      • 配置文件
      • 具体类
    • serviceB代码
      • pom文件
      • 配置文件
      • 具体类
  • 实现效果
  • 四、总结
  • 五、升华

一、背景介绍

之前在项目开发的过程中,对于Nacos的理解停留在实际运用层面。但是仅仅停留在运用层面是不够的。所以就对nacos的基本原理进行了理论学习,并且对nacos的服务注册包括健康检查机制(心跳机制),nacos的配置管理进行了代码实现。

二、 思路方案

项目整体结构:1.有服务A和服务B分别集成了nacosSDK(类似与此前的项目引入了nacos的相关依赖);2.nacosService服务端中分别有两个核心的服务注册和配置管理。

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

三、过程

项目框架为spring boot框架

nacosService代码

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>org.example</groupId><artifactId>client</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
</project>

配置文件

server:port: 8200

具体类

package com.wangwei.client;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class nacosServiceApplication {public static void main(String[] args) {SpringApplication.run(nacosServiceApplication.class, args);}}
package com.wangwei.client;import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;import java.time.Duration;/*** @author : [WangWei]* @version : [v1.0]* @className : RestTemplateConfig* @description : [RestTemplateConfig配置类创建一个RestTemplate Bean,并在其上配置一些属性,如连接超时时间、读取超时时间等。这些属性将影响RestTemplate的行为]* @createTime : [2023/4/15 20:15]* @updateUser : [WangWei]* @updateTime : [2023/4/15 20:15]* @updateRemark : [描述说明本次修改内容]*/
@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {return builder.setConnectTimeout(Duration.ofSeconds(1000)).setReadTimeout(Duration.ofSeconds(1000)).build();}}
package com.wangwei.client;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;/*** @author : [WangWei]* @version : [v1.0]* @className : com.wangwei.client.ConfigController* @description : [描述说明该类的功能]* @createTime : [2023/6/5 20:23]* @updateUser : [WangWei]* @updateTime : [2023/6/5 20:23]* @updateRemark : [描述说明本次修改内容]*/
@RestController
@RequestMapping("/nacosService")
public class ServeController {@AutowiredRestTemplate restTemplate;Map<Object, Map<Object, Object>> registerMap = new HashMap<>();Map<Object, Map<Object, Object>> configMap = new HashMap<>();/** @description:获取配置信息* @author: wangwei* @date: 2023/7/21 17:13* @param: []* @return: java.util.Map<java.lang.Object,java.lang.Object>**/@GetMapping("/getConfig")public Map<Object,Object> getConfig(){Map<Object,Object>configurationInfo=new HashMap<>();for (Map.Entry<Object,Map<Object,Object>> map:configMap.entrySet()) {Object mapKey = map.getKey();Map<Object, Object> value = map.getValue();configurationInfo.put(mapKey,value);}return configurationInfo;}/** @description:获取注册信息* @author: wangwei* @date: 2023/7/21 17:12* @param: []* @return: java.util.Map<java.lang.Object,java.lang.Object>**/@GetMapping("/getRegister")public  Map<Object, Object> getRegister(){Map<Object,Object>registrationInfo=new HashMap<>();for (Map.Entry<Object,Map<Object,Object>> map:registerMap.entrySet()) {Object mapKey = map.getKey();Map<Object, Object> value = map.getValue();registrationInfo.put(mapKey,value);}return registrationInfo;}/** @description:进行服务注册* @author: wangwei* @date: 2023/7/21 17:07* @param: [registMap]* @return: java.lang.String**/@PostMapping("/regist")public String regist(@RequestBody Map<Object,Object> registMap){registerMap.put( registMap.get("serviceName"), (Map<Object, Object>) registMap.get("serviceValue"));this.notice();System.out.println(registMap);Map<Object ,Object> serviceValue =(Map<Object, Object>) registMap.get("serviceValue");//服务注册成功之后为该服务开启心跳定时任务this.heartBeatTask(serviceValue);return "服务注册成功!!!";}/** @description:根据注册表中的注解信息通知对应的服务* @author: wangwei* @date: 2023/7/22 8:21* @param: [registMap]* @return: void**/public void notice() {for (Map.Entry<Object, Map<Object, Object>> entry : registerMap.entrySet()) {Map<Object, Object> value = entry.getValue();String ip= value.get("ipAddress")+":"+value.get("port");String url = "http://"+ip+"/getRegisterInfo";System.out.println(registerMap);restTemplate.getForObject(url,Map.class);}}/** @description:修改配置信息并通知给对应的服务,来获取最新的配置* @author: wangwei* @date: 2023/7/21 11:13* @param: [config]* @return: java.lang.String**/@PostMapping("/setConfig")public String setConfig(@RequestBody Map<String,Object> configInfo) {configMap.put( configInfo.get("serviceName"), (Map<Object,Object>) configInfo.get("serviceValue"));if(registerMap.containsKey(String.valueOf(configInfo.get("serviceName")))) {Map<Object,Object> registrationInfo = registerMap.get(String.valueOf(configInfo.get("serviceName")));String ip= registrationInfo.get("ipAddress")+":"+registrationInfo.get("port");String url = "http://"+ip+"/getConfigInfo";//通知对应的服务restTemplate.getForObject(url,Map.class);}System.out.println(configInfo);return "配置注册成功!!!";}/** @description:给注册上的服务开启心跳任务* @author: wangwei* @date: 2023/7/22 8:32* @param: [registrationInfo]* @return: void**/private void heartBeatTask(Map<Object,Object> registrationInfo) {// 创建一个定时任务调度器,该调度器可以执行定时任务ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);CountDownLatch latch = new CountDownLatch(1); // 创建一个CountDownLatch,初始值为1String ip = registrationInfo.get("ipAddress") + ":" + registrationInfo.get("port");String url ="http://"+ ip + "/heartBeatCheck";// 定义一个心跳任务,使用匿名内部类实现Runnable接口Runnable heartbeatTask = new Runnable() {@Overridepublic void run() {try {restTemplate.getForObject(url, boolean.class);System.out.println("心跳检查" + ip);} catch (Exception e) {// 关闭定时任务调度器scheduler.shutdown();// 将该服务从注册表中删除registerMap.remove(registrationInfo.get("serviceName"));//通知注册表中的其他服务,来获取最细的注册表信息notice();}}};// 使用定时任务调度器,每5秒执行一次心跳任务,并将ScheduledFuture对象传递给任务scheduler.scheduleAtFixedRate(heartbeatTask, 0, 5, TimeUnit.SECONDS);}}

nacosSDK代码

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.wangwei</groupId><artifactId>nacosSDK</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies></project>

配置类

server:port: 8100

具体类

package com.wangwei.client;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class nacosSDKApplication {public static void main(String[] args) {SpringApplication.run(nacosSDKApplication.class, args);}}
package com.wangwei.client;import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;import java.time.Duration;/*** @author : [WangWei]* @version : [v1.0]* @className : RestTemplateConfig* @description : [RestTemplateConfig配置类创建一个RestTemplate Bean,并在其上配置一些属性,如连接超时时间、读取超时时间等。这些属性将影响RestTemplate的行为]* @createTime : [2023/4/15 20:15]* @updateUser : [WangWei]* @updateTime : [2023/4/15 20:15]* @updateRemark : [描述说明本次修改内容]*/
@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {return builder.setConnectTimeout(Duration.ofSeconds(1000)).setReadTimeout(Duration.ofSeconds(1000)).build();}}
package com.wangwei.client;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;/*** @author : [WangWei]* @version : [v1.0]* @className : ServerConfig* @description : [程序启动时执行]* @createTime : [2023/6/6 19:49]* @updateUser : [WangWei]* @updateTime : [2023/6/6 19:49]* @updateRemark : [描述说明本次修改内容]*/
@Component
public class ServerConfig implements ApplicationRunner {@Value("${server.name}")private String name;@Value("${server.port}")private String port;@Value("${server.nacosUrl}")private String nacosUrl;@Autowiredprivate RestTemplate restTemplate;/** @description:程序启动之后该方法,将服务注册到nacos的注册中心* @author: wangwei* @date: 2023/7/21 10:42* @param: [args]* @return: void**/@Overridepublic void run(ApplicationArguments args) throws Exception {String ipAddress=null;//获取本机的ip地址ipAddress = InetAddress.getLocalHost().getHostAddress();// 构建请求体Map<Object, Object> requestBody = new HashMap<>();requestBody.put("serviceName",name);Map<String, Object> serviceValue = new HashMap<>();serviceValue.put("ipAddress", ipAddress);serviceValue.put("port", this.port);serviceValue.put("serviceName",name);requestBody.put("serviceValue",serviceValue);// 发送POST请求String url = "http://"+nacosUrl+"/nacosService/regist";String response = restTemplate.postForObject(url, requestBody, String.class);System.out.println("已经注册到nacos中"+response);}
}
package com.wangwei.client;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.HashMap;
import java.util.Map;/*** @author : [WangWei]* @version : [v1.0]* @className : com.wangwei.client.ConfigController* @description : [描述说明该类的功能]* @createTime : [2023/6/5 20:23]* @updateUser : [WangWei]* @updateTime : [2023/6/5 20:23]* @updateRemark : [描述说明本次修改内容]*/
@RestController
public class ConfigController {@Value("${server.name}")private String name;@Value("${server.nacosUrl}")private String nacosUrl;public Map<Object,Object>configMap=new HashMap<>();public Map<Object,Object>registerMap=new HashMap<>();public Map<Object, Object> getConfigMap() {return configMap;}public void setConfigMap(Map<Object, Object> configMap) {this.configMap = configMap;}public Map<Object, Object> getRegisterMap() {return registerMap;}public void setRegisterMap(Map<Object, Object> registerMap) {this.registerMap = registerMap;}@AutowiredRestTemplate restTemplate;/*** @description:从serve中获取配置信息* @author: wangwei* @date: 2023/6/5 20:57* @param: []* @return: void**/@GetMapping("/getConfigInfo")public Map<Object, Object> getConfig(){// 发送 GET 请求// 定义请求的URL和参数String url = "http://"+nacosUrl+"/nacosService/getConfig";Map<Object,Object>response = (Map<Object, Object>) restTemplate.getForObject(url, Map.class);configMap.clear();configMap.putAll(response);return configMap;}//获取注册信息@GetMapping("/getRegisterInfo")public  Map<Object, Object> getRegister(){// 发送 GET 请求// 定义请求的URL和参数String url = "http://"+nacosUrl+"/nacosService/getRegister";Map<Object,Object>response = (Map<Object, Object>) restTemplate.getForObject(url, Map.class);//将过期的缓存注册表信息清空registerMap.clear();registerMap.putAll(response);System.out.println("已经更新最新的注册表信息"+registerMap);return registerMap;}/** @description:更具服务名称,返回服务的ip* @author: wangwei* @date: 2023/7/25 8:30* @param: [serviceName]* @return: java.lang.String**/@GetMapping("/getIp{serviceName}")public String getIp(@PathVariable String serviceName){Map<Object, Object> objectMap = (Map<Object, Object>)registerMap.get(serviceName);String ip=objectMap.get("ipAddress")+":"+objectMap.get("port");return ip;}/** @description:心跳检查* @author: wangwei* @date: 2023/7/21 16:01* @param: []* @return: boolean**/@GetMapping("/heartBeatCheck")public boolean heartBeatCheck(){return true;}}

serviceA代码

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>serviceA</artifactId><version>0.0.1-SNAPSHOT</version><name>NacosService</name><description>NacosService</description><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- nacosSDK依赖--><dependency><groupId>com.wangwei</groupId><artifactId>nacosSDK</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置文件

server:name: serviceAport: 8300nacosUrl: 192.168.109.60:8200

具体类

package com.wangwei.client;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class ServiceAApplication {public static void main(String[] args) {SpringApplication.run(ServiceAApplication.class, args);}
}
package com.wangwei.client;import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;import java.time.Duration;/*** @author : [WangWei]* @version : [v1.0]* @className : RestTemplateConfig* @description : [RestTemplateConfig配置类创建一个RestTemplate Bean,并在其上配置一些属性,如连接超时时间、读取超时时间等。这些属性将影响RestTemplate的行为]* @createTime : [2023/4/15 20:15]* @updateUser : [WangWei]* @updateTime : [2023/4/15 20:15]* @updateRemark : [描述说明本次修改内容]*/
@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {return builder.setConnectTimeout(Duration.ofSeconds(1000)).setReadTimeout(Duration.ofSeconds(1000)).build();}}
package com.wangwei.client;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.Map;@RestController
@RequestMapping("/serviceA")
public class ServiceA {@AutowiredConfigController configController;@AutowiredRestTemplate restTemplate;/** @description:获取该服务的配置信息* @author: wangwei* @date: 2023/7/21 20:57* @param: []* @return: java.util.Map<java.lang.Object,java.lang.Object>**/@GetMapping("/getConfigInfo")public Map<Object,Object> getConfig(){Map<Object, Object> config = configController.getConfig();Map <Object,Object> configurationInfo= (Map<Object, Object>) config.get("serviceA");// 打印目标Map中的值for (Map.Entry<Object, Object> entry : configurationInfo.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}return config;}/** @description:从注册表中获取注册信息* @author: wangwei* @date: 2023/7/21 20:56* @param: []* @return: java.util.Map<java.lang.Object,java.lang.Object>**/@GetMapping("/getRegister")public Map<Object,Object> Register() {Map<Object, Object> register = configController.getRegister();// 打印目标Map中的值for (Map.Entry<Object, Object> entry : register.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}return register;}@GetMapping("/sendMessageToB")public String sendMessageToB(){String ip = configController.getIp("serviceB");// 定义请求的URL和参数String url = "http://"+ip+"/serviceB/test";// 发送 GET 请求并获取响应ResponseEntity<String> response = restTemplate.getForEntity(url,String.class);// 获取响应结果if (response.getStatusCode().is2xxSuccessful()) {Object responseBody = response.getBody();System.out.println("Response: " + responseBody);} else {System.out.println("Request failed with status code: " + response.getStatusCodeValue());}return "给B发送消息成功!!!";}}

serviceB代码

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>ServiceB</artifactId><version>0.0.1-SNAPSHOT</version><name>NacosService</name><description>NacosService</description><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--nacosSDK--><dependency><groupId>com.wangwei</groupId><artifactId>nacosSDK</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置文件

server:name: serviceBport: 8500nacosUrl: 192.168.109.60:8200

具体类

package com.wangwei.client;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class ServiceBApplication {public static void main(String[] args) {SpringApplication.run(ServiceBApplication.class, args);}
}
package com.wangwei.client;import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;import java.time.Duration;/*** @author : [WangWei]* @version : [v1.0]* @className : RestTemplateConfig* @description : [RestTemplateConfig配置类创建一个RestTemplate Bean,并在其上配置一些属性,如连接超时时间、读取超时时间等。这些属性将影响RestTemplate的行为]* @createTime : [2023/4/15 20:15]* @updateUser : [WangWei]* @updateTime : [2023/4/15 20:15]* @updateRemark : [描述说明本次修改内容]*/
@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {return builder.setConnectTimeout(Duration.ofSeconds(1000)).setReadTimeout(Duration.ofSeconds(1000)).build();}}
package com.wangwei.client;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.Map;@RestController
@RequestMapping("/serviceB")
public class ServiceB {@AutowiredRestTemplate restTemplate;@AutowiredConfigController configController;/** @description:获取该服务的配置信息* @author: wangwei* @date: 2023/7/21 20:57* @param: []* @return: java.util.Map<java.lang.Object,java.lang.Object>**/@GetMapping("/getConfig")public Map<Object,Object> getConfig(){Map<Object, Object> config = configController.getConfig();Map <Object,Object> configurationInfo= (Map<Object, Object>) config.get("serviceB");// 打印目标Map中的值for (Map.Entry<Object, Object> entry : configurationInfo.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}return config;}@GetMapping("/getRegister")public Map<Object,Object> Register() {Map<Object, Object> register = configController.getRegister();// 打印目标Map中的值for (Map.Entry<Object, Object> entry : register.entrySet()) {System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}return register;}@GetMapping("/test")public void testA(){System.out.println("我被A服务调用了");}}

实现效果

先启动nacosService,再依次启动serviceB、serviceA。

  1. 服务启动时注册到nacos的服务管理中

serviceA:
在这里插入图片描述

serviceB:
在这里插入图片描述
2. 服务注册成功之后后,nacosService为该实例创建一个心跳定时任务,服务需要定期向nacos注册中心发送心跳请求,如果没有收到心跳请求则将该服务信息从注册表中删除。

nacosService:
在这里插入图片描述
这个时候一旦有服务挂掉,会将该服务的注册信息进行删除,并将最新的注册信息同步给其他服务。
例如:serviceA挂掉了

nacosService:
在这里插入图片描述
serviceB:
在这里插入图片描述

  1. 修改配置信息会通知服务来来获取最新的配置信息
    在这里插入图片描述
  2. A请求B时,将B的服务名称在nacosSDK中转换为实际B服务的ip+端口号进行请求
    在这里插入图片描述
    ServiceB:
    在这里插入图片描述

四、总结

  1. 理论和实践的结合,才能反过来指导理论。
  2. 本篇博客只是简单的实现了nacos的注册中心和配置管理,nacos还有很多的功能模块,并且本篇博客对于代码的健壮性是没有进行考虑的。
  3. 能够将nacos的基本原理进行理解,并通过代码实现。需要感谢马总的指导和帮助。并且本篇博客也借鉴了马总的总结。例如通过以图形的方式来表示清晰简洁的表现思路、服务之间的依赖关系。我都从中学习了很多,这也侧面说明了学习是一个反复的过程。

五、升华

站在巨人的肩膀上学习。
不将就就是发现的原动力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/6732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# List 详解五

目录 26.GetType() 27.IndexOf(T) 28.IndexOf(T, Int32) 29.IndexOf(T, Int32, Int32) 30.Insert(Int32, T) 31.InsertRange(Int32, IEnumerable) 32.LastIndexOf(T) 33.LastIndexOf(T, Int32) 34.LastIndexOf(T, Int32, Int32) …

【CAS6.6源码解析】调试Rest API接口

CAS的web层默认是基于webflow实现的&#xff0c;ui和后端是耦合在一起的&#xff0c;做前后端分离调用和调试的时候不太方便。但是好在CAS已经添加了支持Rest API的support模块&#xff0c;添加相应模块即可。 文章目录 添加依赖并重新build效果 添加依赖并重新build 具体添加…

32位Cortex-M4 MCU:LPC54607J256ET180E、LPC54605J512BD100K 180MHz嵌入式微控制器

LPC546xx 32 位微控制器(MCU) 具有丰富的外设集、极低的功耗和增强的调试功能。 LPC546xx MCU系列采用ARM Cortex-M4内核&#xff0c;可提供以太网支持&#xff0c;并设有一个TFT LCD控制器和两个CAN FD模块。LPC546xx MCU旨在提高灵活性和性能可扩展性&#xff0c;可提供高达1…

Vue3 Vite electron 开发桌面程序

Electron是一个跨平台的桌面应用程序开发框架&#xff0c;它允许开发人员使用Web技术&#xff08;如HTML、CSS和JavaScript&#xff09;构建桌面应用程序&#xff0c;这些应用程序可以在Windows、macOS和Linux等操作系统上运行。 Electron的核心是Chromium浏览器内核和Node.js…

ABAP 为N的一个数,在原来基础上浮动在-30~30

需求&#xff1a;为N的一个数&#xff0c;在原来基础上浮动在-30~30 *&---------------------------------------------------------------------* *& Report ZZZZ111 *&---------------------------------------------------------------------* *& 需求&…

【算法基础:搜索与图论】3.4 求最短路算法(Dijkstrabellman-fordspfaFloyd)

文章目录 求最短路算法总览Dijkstra朴素 Dijkstra 算法&#xff08;⭐原理讲解&#xff01;⭐重要&#xff01;&#xff09;&#xff08;用于稠密图&#xff09;例题&#xff1a;849. Dijkstra求最短路 I代码1——使用邻接表代码2——使用邻接矩阵 补充&#xff1a;稠密图和稀疏…

npm i babel-plugin-import -D之后报错

替换modules/.bin/XX文件 1.vue-cli-service #!/bin/sh basedir$(dirname "$(echo "$0" | sed -e s,\\,/,g)")case uname in*CYGWIN*) basedircygpath -w "$basedir";; esacif [ -x "$basedir/node" ]; then"$basedir/node"…

【NLP】视觉变压器与卷积神经网络

一、说明 本篇是 变压器因其计算效率和可扩展性而成为NLP的首选模型。在计算机视觉中&#xff0c;卷积神经网络&#xff08;CNN&#xff09;架构仍然占主导地位&#xff0c;但一些研究人员已经尝试将CNN与自我注意相结合。作者尝试将标准变压器直接应用于图像&#xff0c;发现在…

CAXA中.exb或者.dwg文件保存为PDF

通常CAXAZ中的文件为.exb或者.dwg格式&#xff0c;我们想打印或者保存为PDF文件格式&#xff0c;那么就用一下的方法&#xff1a; CAXA文件如图所示&#xff1a; 框选出你要打印的图纸&#xff01;&#xff01;&#xff01;&#xff01; 我们选择"菜单"->"…

【算法基础:搜索与图论】3.5 求最小生成树算法(PrimKruskal)

文章目录 最小生成树介绍朴素Prim算法算法思路⭐例题&#xff1a;858. Prim算法求最小生成树 Kruskal算法算法思路⭐例题&#xff1a;859. Kruskal算法求最小生成树 最小生成树介绍 最小生成树 有关树的定义 生成子图&#xff1a;生成子图是从原图中选取部分节点以及这些节点…

Keepalived热备、Keepalived+LVS、HAProxy监控及后端服务器健康检查、负载均衡调度器对比

day02 day02KeepAlived高可用集群配置高可用的web集群监控本机80端口&#xff0c;实现主备切换实现原理实施配置高可用、负载均衡的web集群配置高可用、负载均衡HAProxy配置haproxy负载均衡调度器比较LVS&#xff08;Linux Virtual Server&#xff09;NginxHAProxy KeepAlive…

Pytorch个人学习记录总结 08

目录 神经网络-搭建小实战和Sequential的使用 版本1——未用Sequential 版本2——用Sequential 神经网络-搭建小实战和Sequential的使用 torch.nn.Sequential的官方文档地址&#xff0c;模块将按照它们在构造函数中传递的顺序添加。代码实现的是下图&#xff1a; 版本1—…

16_LinuxLCD驱动

目录 Framebuffer设备 LCD驱动简析 LCD驱动程序编写 LCD屏幕参数节点信息修改 LCD 屏幕背光节点信息 使能Linux logo显示 设置LCD作为终端控制台 Framebuffer设备 先来回顾一下裸机的时候LCD驱动是怎么编写的,裸机LCD驱动编写流程如下: 1.初始化I.MX6U的eLCDIF控制器,…

Jenkins发送的邮箱中没有带配置的压缩附件

【问题描述】&#xff1a;Jenkins中明明配置了邮箱发送时要带压缩附件&#xff0c;收到的邮箱中却没有附件内容 【问题定位】&#xff1a;压缩附件没有放在Jenkins工作空间下&#xff0c;所以发送的邮件并未发送附件 【解决办法】&#xff1a; 1&#xff09;把压缩附件放到J…

kubernetes持久化存储卷

kubernetes持久化存储卷 kubernetes持久化存储卷一、存储卷介绍二、存储卷的分类三、存储卷的选择四、本地存储卷之emptyDir五、本地存储卷之 hostPath六、网络存储卷之nfs七、PV(持久存储卷)与PVC(持久存储卷声明)7.1 认识pv与pvc7.2 pv与pvc之间的关系7.3 实现nfs类型pv与pvc…

Spring MVC拦截器和跨域请求

一、拦截器简介 SpringMVC的拦截器&#xff08;Interceptor&#xff09;也是AOP思想的一种实现方式。它与Servlet的过滤器&#xff08;Filter&#xff09;功能类似&#xff0c;主要用于拦截用户的请求并做相应的处理&#xff0c;通常应用在权限验证、记录请求信息的日志、判断用…

EfficientNetV2: Smaller Models and Faster Training

EfficientNetV2: Smaller Models and Faster Training 1.Abstract 本文提出了一种训练速度快、参数量少、模型小的卷积神经网络EfficientNetV2。 训练采用了NAS感知技术与缩放技术对训练速度与参数数量进行联合优化。 NAS感知技术&#xff1a; 全名是神经架构搜索&#xff0…

quartus工具篇——ROM ip核

quartus工具篇——ROM ip核 1、ROM简介 FPGA中的ROM(Read-Only Memory)是一种只读存储器,主要用来存储固化的初始化配置数据。FPGA ROM的特性主要有: 预编程初始化 - ROM在FPGA编程时就已经写入了初始值,这些值在整个工作周期保持不变。初始化配置 - ROM通常用来存储FPGA的初…

Flutter的开发环境搭建-图解

前言&#xff1a;Flutter作为一个移动应用开发框架&#xff0c;具有许多优点和一些局限性。最大的优点就是-跨平台开发&#xff1a;Flutter可以在iOS和Android等多个平台上进行跨平台开发&#xff0c;使用一套代码编写应用程序&#xff0c;节省开发时间和成本。 Flutter可以编…

JVM运行时数据区——方法区、堆、栈的关系

方法区存储加载的字节码文件内的相关信息和运行时常量池&#xff0c;方法区可以看作是独立于Java堆的内存空间&#xff0c;方法区是在JVM启动时创建的&#xff0c;其内存的大小可以调整&#xff0c;是线程共享的&#xff0c;并且也会出现内存溢出的情况&#xff0c;也可存在垃圾…