Nacos
windows启动单机Nacos:bin目录下
startup.cmd -m standalone
;
# 服务注册
# 引入依赖
在父工程中:加入SpringCloudAlibaba的依赖;
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
2
3
4
5
6
7
各子模块引入nacos-discovery依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2
3
4
# 配置
yml文件中添加nacos地址:
spring:
cloud:
nacos:
server-addr: localhost:8848
2
3
4
# 添加到集群
yml文件中:
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HZ # 集群名称 HZ杭州
2
3
4
5
6
更改配置启动:
复制一个服务启动配置,添加属性:
-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH
1
# 环境隔离
新建一个dev环境,在Nacos控制台上可以看到:
yml中配置:
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HZ
namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间,填ID
2
3
4
5
6
7
# 配置管理
Nacos控制台中配置列表中新建:
# 拉取配置
微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动;
如果尚未读取application.yml,又如何得知nacos地址呢?
spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读;
配置文件读取流程:
子模块中引入nacos-config的客户端依赖:
<!--nacos配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2
3
4
5
添加bootstrap.yaml:
spring:
application:
name: userservice # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
config:
file-extension: yaml # 文件后缀名
2
3
4
5
6
7
8
9
10
- 先根据spring.cloud.nacos.server-addr获取nacos地址;
- 再根据
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
作为文件id,来读取配置;
# 读取Nacos配置
在user-service中的UserController中添加业务逻辑,读取pattern.dateformat配置:
# 配置热更新
修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新;
已将配置加了前缀:pattern:
方式一:在@Value注入的变量所在类上添加注解@RefreshScope;
@Slf4j @RestController @RequestMapping("/user") @RefreshScope public class UserController{ @Value("${pattern.dateformat}") private String dateformat; }
1
2
3
4
5
6
7
8方式二:使用@ConfigurationProperties注解代替@Value注解;
额外添加一个类专门读取patterrn.dateformat属性:
@Component @Data @ConfigurationProperties(prefix = "pattern") public class PatternProperties { private String dateformat; }
1
2
3
4
5
6在Controller中:
@Autowired private PatternProperties patternProperties; @GetMapping("/now") public String now(){ return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat())); }
1
2
3
4
5
6
7
# 配置共享
配置优先级:当nacos、服务本地同时出现相同属性时,优先级有高低之分;
- 当前环境配置,如:userservice-dev.yaml;
- 不包含环境,可以被多个环境共享,如:userservice.yaml;
案例:
在Nacos中添加一个共享配置:
服务中读取共享配置:
@Component @Data @ConfigurationProperties(prefix = "pattern") public class PatternProperties { private String dateformat; private String envSharedValue; }
1
2
3
4
5
6
7@RequestMapping("/user") public class UserController{ @Autowired private UserService userService; @Autowired private PatternProperties patternProperties; @GetMapping("/prop") public PatternProperties prop(){ return patternProperties; } }
1
2
3
4
5
6
7
8
9
10
11
12运行两个UserApplication,使用不同profile;
改为dev与test;
复制服务修改profile值:
访问两个不同服务:
访问http://localhost:8081/user/prop,结果:
访问http://localhost:8082/user/prop,结果:
dateformat为环境配置,envSharedValue为共享配置;
# 注册表结构
# 多级存储模型
Nacos采用了数据的分级存储模型:
- Namespace,用来环境隔离;
- Group,用来服务分组;
- Service,一个服务包含多个实例;
- Cluster,一个服务下的实例可能处于不同机房,所以Service下多个集群;
- Instance,实例;
Nacos源码中采用多层Map表示,结构为Map<String,Map<String,Service>>,最外层Map的key是namespaceId,内层的key是group拼接的serviceName,值是Service对象;Service对象内部也是一个Map,key是集群名称,值是Cluster对象,Cluster对象内部维护了Instance的集合;
# 高并发注册
Nacos内部收到注册请求时,不会立即写数据,而是将服务注册的任务放入一个阻塞队列就立即响应给客户端,然后利用线程池读取阻塞队列中任务,异步完成实例更新,从而提高并发写能力;
自动注册源码:https://juejin.cn/post/7263844088545738789
# 如何感知配置中心变更?
本质上就用长连接实现,客户端维护了与服务端的长连接,只要有配置变更了,就告知客户端更新;
# 与Eureka区别?
- Nacos与eureka的共同点
- 都支持服务注册和服务拉取;
- 都支持服务提供者心跳方式做健康检测;
- Nacos与Eureka的区别
- Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式;
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除;
- Nacos支持服务列表变更的消息推送模式,服务列表更新更及时;
- Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式;
# Nacos Client简单工厂模式
在Nacos的client中,提供了一个NacosFactory的工厂类,该类统一提供了创建ConfigService(配置中心服务)、NamingService(注册中心服务)和NamingMaintainService(注册中心实例操作服务)的实例化方法。
public class NacosFactory {
public static ConfigService createConfigService(Properties properties) throws NacosException {
return ConfigFactory.createConfigService(properties);
}
public static NamingService createNamingService(Properties properties) throws NacosException {
return NamingFactory.createNamingService(properties);
}
// ... 省略其他方法
}
2
3
4
5
6
7
8
9
10
11
12