本文介绍了一些关于SpringCloud Nacos的基本概念与应用。

Nacos服务注册

首先父模块的依赖控制处需要添加spring cloud alibaba

<!-- SpringCloudAlibaba有关依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>

接着在服务模块的pom中添加spring-cloud-starter-alibaba-nacos-discovery依赖

<!--nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

更改配置,nacos是在springcloud配置中的

spring:
cloud:
nacos:
server-addr: localhost:8848

注:EnableDiscoveryClient注解现在是可选项了,只要依赖了以spring-cloud-starter-netflix为前缀的库(例如spring-cloud-starter-netflix-eureka-client),就启用了服务注册发现功能;

服务分层架构

Nacos的服务按照服务->集群->实例来分层,优先调用本地集群内的实例,本地集群中实例不可用再调用其他集群的实例

spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HangZhou # 集群名称

负载均衡策略

如果想要配置优先调用本地集群内的实例,需要修改nacos的配置,例如订单服务想要优先调用本地用户服务的实例,需要使用nacos的负载均衡策略

userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 规则类的名称

NacosRule优先选择本地集群,集群内部随机选择;当本地集群健康服务数为0时,选择跨集群访问并警告

权重配置

控制台可以修改实例的权重,权重越高,用户请求更多的向该实例迁移。在服务升级中,可以通过将权重比例调为0然后进行升级,之后再调成小权重进行一段时间测试,稳定后恢复权重

NameSpace

环境隔离,对相似的服务可以进行分组,如果不同组的服务也无法相互访问。每个namespace有唯一的id,需要在配置文件中修改它的值来设置环境

Nacos和Eureka的区别

健康监测

对于服务提供者的健康状态监测,nacos将服务实例分为临时实例和非临时实例

临时实例:

和Eureka一样,使用心跳检测,如果不在服务就会主动剔除(默认情况下如果不配置,实例都是临时的)

非临时实例:

非临时实例则会由nacos主动发起询问服务实例的健康状态,并且不会将不健康的服务实例清楚,会等待恢复

创建非临时实例只需要修改discovery的值

spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HangZhou # 集群名称
ephemeral: false # 是否为临时实例

服务列表

Eureka和Nacos都会定时拉取服务列表加到缓存中,提高效率。但是Nacos还采取了消息推送的形式,当服务发生变更,会主动推送消息给消费者

配置管理

配置设置

命名规则是 服务名-运行环境.yaml如userservice-dev.yaml

配置内容只设置有热更新需求的配置项,例如日期格式等;像数据库地址这种可以不放上去

配置拉取

配置读取步骤:

image-20230901202139446.png

bootstap.yml配置的优先级较高,可以读取到nacos的地址,再读取nacos的配置文件,最后读取application.yml的配置文件

首先在微服务引入nacos-config依赖

<!--nacos config依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

接着创建bootstrap.yml文件,引导配置文件,优先级高于application.yml

spring:
application:
name: user-service # 服务名称
profiles:
active: dev # 开发环境
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
config:
file-extension: yaml # 文件后缀名

三者结合发现就是在控制台创建的配置id即userservice-dev.yaml

同时,之前的application.yml中的重复配置可以删除了,如服务名称和nacos地址

注:nacos配置管理是按服务分的,因此写在微服务模块中

配置热更新

前置知识:

使用@Value(“${pattern.dateformat}”)注解可以获取配置项(改成NacosValue)

@ConfigurationProperties(prefix = “xxx”) 约定大于配置,只要prefix前缀xxx与变量名进行拼接与配置一致,就可以注入

方法一:在Value注解所在类上加一个注解@RefreshScope,可以实现配置热更新,无需重启服务

方法二:使用@ConfigurationProperties(prefix = “xxx”)注解

小插曲

浪费了近一个小时时间在处理依赖和配置的问题上。这里属于是对dependencymanagement不熟悉了。

使用dependencyManagement可以统一管理项目的版本号,确保应用的各个项目的依赖和版本一致,不用每个模块项目都弄一个版本号,不利于管理,当需要变更版本号的时候只需要在父类容器里更新,不需要任何一个子项目的修改;如果某个子项目需要另外一个特殊的版本号时,只需要在自己的模块dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。

误解:以为在父模块中定义dependencyManagement之后,子模块就可以继承下来,但是在maven中发现子模块中并没有继承下来依赖。实际上是子模块中依然需要添加相关依赖但是不用加版本号。

解决方法:想要实现我的需求只需要将父模块的依赖标签dependencyManagement删除,仅使用dependencies即可

<dependencies>

<!--nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!--mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>

<!--mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>

<!--web起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

</dependencies>