手写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 {
@Bean
public 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 {
@Autowired
RestTemplate 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,初始值为1
String ip = registrationInfo.get("ipAddress") + ":" + registrationInfo.get("port");
String url ="http://"+ ip + "/heartBeatCheck";
// 定义一个心跳任务,使用匿名内部类实现Runnable接口
Runnable heartbeatTask = new Runnable() {
@Override
public 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 {
@Bean
public 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;
@Autowired
private RestTemplate restTemplate;
/*
* @description:程序启动之后该方法,将服务注册到nacos的注册中心
* @author: wangwei
* @date: 2023/7/21 10:42
* @param: [args]
* @return: void
**/
@Override
public 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;
}
@Autowired
RestTemplate 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: serviceA
port: 8300
nacosUrl: 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 {
@Bean
public 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 {
@Autowired
ConfigController configController;
@Autowired
RestTemplate 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: serviceB
port: 8500
nacosUrl: 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 {
@Bean
public 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 {
@Autowired
RestTemplate restTemplate;
@Autowired
ConfigController 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的基本原理进行理解,并通过代码实现。需要感谢马总的指导和帮助。并且本篇博客也借鉴了马总的总结。例如通过以图形的方式来表示清晰简洁的表现思路、服务之间的依赖关系。我都从中学习了很多,这也侧面说明了学习是一个反复的过程。
五、升华
站在巨人的肩膀上学习。
不将就就是发现的原动力。