手写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。
- 服务启动时注册到nacos的服务管理中
serviceA:
serviceB:
2. 服务注册成功之后后,nacosService为该实例创建一个心跳定时任务,服务需要定期向nacos注册中心发送心跳请求,如果没有收到心跳请求则将该服务信息从注册表中删除。
nacosService:
这个时候一旦有服务挂掉,会将该服务的注册信息进行删除,并将最新的注册信息同步给其他服务。
例如:serviceA挂掉了
nacosService:
serviceB:
- 修改配置信息会通知服务来来获取最新的配置信息
- A请求B时,将B的服务名称在nacosSDK中转换为实际B服务的ip+端口号进行请求
ServiceB:
四、总结
- 理论和实践的结合,才能反过来指导理论。
- 本篇博客只是简单的实现了nacos的注册中心和配置管理,nacos还有很多的功能模块,并且本篇博客对于代码的健壮性是没有进行考虑的。
- 能够将nacos的基本原理进行理解,并通过代码实现。需要感谢马总的指导和帮助。并且本篇博客也借鉴了马总的总结。例如通过以图形的方式来表示清晰简洁的表现思路、服务之间的依赖关系。我都从中学习了很多,这也侧面说明了学习是一个反复的过程。
五、升华
站在巨人的肩膀上学习。
不将就就是发现的原动力。