<!-- nacos 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${nacos.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
一、初识 Nacos
1. Nacos 的环境安装与测试
Nacos 是阿里巴巴的产品,现在是 SpringBoot 中的一个组件。相比 Eureka 功能更加丰富,在国内受欢迎程度较高。Nacos 的官网是 Nacos官网| Nacos 配置中心 | Nacos 下载| Nacos 官方社区 | Nacos 官网
安装好 Nacos 之后可以进入到其 bin 文件夹,双击startup.cmd 命令。也可通过指令打开 nacos
startup.cmd -m standalone
启动后界面如下,复制链接 http://10.183.72.85:8848/nacos/index.html 到浏览器打开
nacos 管理登录页如下,用户名和密码默认都是 nacos。至此 nacos 的环境安装就做好了。
2. nacos 的使用
Nacos 是 SpringCloudAlibaba (阿里巴巴)的组件,而 SpringCloudAlibaba 也遵循 SpringCloud 中定义的服务注册、服务发现规范。因此使用 Nacos 和使用 Eureka 对于微服务来说,并没有太大区别。差别在于依赖不同、服务地址不同。接下来我们就开始探索如何使用 nacos 吧。
1. 在父工程引入依赖
<!-- nacos 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${nacos.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
2. 在子工程引入 nacos-discovery 依赖;以及在 yml 配置文件配置 nacos 的服务地址
<!-- nacos 客户端依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos 服务地址
3. 启动user-service 和 order-service , 刷新 nacos 的管理网站,发现服务已注册
3. 小结
Nacos 服务搭建
- 下载安装包
- 解压
- 在bin目录下运行指令:startup.cmd -m standalone
注:
-m
参数后面指定的standalone
是一个模式值,表示应用程序将以独立模式启动
Nacos服务注册和发现
- 引入 nacos.discovery 依赖
- 配置 nacos 地址 spring.cloud.nacos.server-addr
二、服务分级存储模型
1. 概念
一个服务有很多实例,例如我们的 每个 user-service 就是一个实例
localhost:8081
localhost:8082
可以把这些实例看作鸡蛋,服务看作菜篮子,把鸡蛋放在同一个菜篮,如果菜篮掉了,鸡蛋就芭比Q了。为了避免这个问题,可以把鸡蛋放在多个菜篮子里,这样一个菜篮子没了,其它菜篮子里还有鸡蛋。Nacos 的服务分级存储模型也引入了这个思想, 把实例分布在各个城市机房,同一个机房的服务就看作是一个集群。简单的说:一个服务(user-service)有多个集群,一个集群有多个实例。
当微服务互相访问时,会先访问本地集群实例,因为本地访问速度快。当本地集群不可用时,才访问其它集群。
Nacos 引入集群概念就是为了降低出现跨集群调用的概率,从而提高访问速度。
2. 集群配置
在服务提供者 user-service 子模块添加集群名称
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos服务端地址
discovery:
cluster-name: HZ # 集群名称,也就是机房所在位置。例如:HZ,杭州
重启实例后,可以在 Nacos 管理网页看到集群的分布和我们设置的一样。
3. 同集群优先配置
在 服务消费者 order-service 的 application.yml 设置负载均衡的 IRule 为 NacosRule, 这个规则会优先寻找自己同集群的服务。
userservice: #要做配置的服务端地址(服务提供则)
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
NacosRule 负载均衡策略
- 有限考虑本地集群服务实例
- 本地服务实例找不到再去找其它集群找可用实例,并且会警告
- 确定了可用实例列表后,采用随机负载均衡挑选一个实例
4. 权重配置
在实际项目部署中每台的机器性能有差异,我们想性能好的机器承担更多的请求。但 NacosRule 默认是同集群随机挑选的,自然不清楚哪台机器的性能好。所有 Nacos 为我们提供了权重配置来控制访问频率,权重越大访问频率越高。默认是1,权重值在[0, 1] 之间。如果设置为0,这台机器永远不会访问。下面说明如何设置权重。
1. 打开 Nacos 管理页面,哪个性能好权重就设高一些,默认是1,权重值在[0, 1] 之间。如果设置为0,这台机器永远不会访问。
5. 环境隔离
Nacos 中服务存储和数据存储的最外层都是一个名为 namespace 的东西, 用来做最外层隔离
在 Nacos 管理页面可以创建 namespace, 用来隔离不同环境。
命名空间--》创建命名空间--》输入 “命名空间” 和 “描述” 信息 --》 确定,就创建好了。
保存后生成了一个空间 ID
在 服务消费者 order-server 模块的 appliacation.yml 配置
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: HZ
namespace: 0484cc4a-3d5c-45dd-b916-d1af0b62b7c4 # 命名空间,填上述ID
重启 order-server 模块,来到 Nacos 管理网页,如下图发现多了一个 dev
此时再次访问数据,发现报错了,原因是 namespace 是唯一的,更改 namespace 后就找不到 userservice。
总的来说归纳以下几点事项 :
- 每个 namespace 都有唯一的 id
- 服务设置时要写 id, 而不是名称
- 不同 namespace 下服务互不可见
6. Nacos 与 Eureka 的区别
Nacos 的服务注册有两种实例:
临时实例:默认类型,服务实例宕机超过一定时间,从服务列表剔除
非临时实例(持久实例):如果实例宕机,不会从服务列表提出。
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为非临时实例
nacos 架构图如下
Eureka 架构图如下
共同点:
- 都支持服务注册和服务拉取;
- 都支持为服务提供者做宕机监测;
不同点:
- Nacos支持服务端主动检测服务提供者状态:临时实例采用心跳模式;非临时实例采用主动检测模式;
- 临时实例心跳不正常会被剔除;非临时实例则不会被剔除;
- Nacos支持服务列表变更的消息推送模式,服务列表更新更及时;
- Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式(A: 可用性; C: 一致性;P: 区间容错性)
三、Nacos 配置管理
1 微服务拉取配置
当微服务部署的实例越来越多,逐个修改微服务配置就容易出错。我们需要一种统一配置管理方案,集中管理所有实例的配置。
Nacos 的配置管理一方面可以可以将配置统一管理;另一方面可以再更新配置后,及时通知微服务,实现热更新。
项目启动之前,会先读取 nacos 配置文件,然后再读取本地配置文件并和 nacos 配置文件合并。
1. 在 user-service 模块的 pom 添加 nacos 配置管理依赖
<!-- nacos 的配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2. 创建 bootstrap.yml 配置依赖,如果本地配置文件有相同部分请去除
spring:
application:
name: userservice
profiles:
active: dev #环境
cloud:
nacos:
server-addr: localhost:8848 # nacos 地址
config:
file-extension: yaml # 文件后缀名
3. 在 user-service 模块的 Controller 层添加测试,读取配置文件中的 dateformat
4. 重启测试, 如下图说明已经成功读取到了我们在nacos中配置的日期格式。
注意:不是所有的配置都适合放在配置中心,维护比较麻烦;建以将一些关键参数,需要运行时调整的参数放到 nacos 配置中心,一般都是自定义的配置
2. 热更新的两种方式
所谓热更新就是修改 nacos 配置后,无需重启实现更新操作。
方式一
在 @Value 注入的变量所在类上添加注解 @RefreshScope
方式二
使用 @ConfigurationProperties 注解代替 @Value 注解。
1. 创建一个配置类 PatternProperties,代码如下
@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dateformat;
}
在 UserController 类注入刚才的 PatternProperties 配置类
整体代码如下
package cn.itcast.user.web;
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private PatternProperties properties;
@GetMapping("/now")
public String now() {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDateformat()));
}
}
四、Nacos 多环境共享配置
微服务启动该时会从 nacos 读取多个配置文件:
-
[spring.application.name]-[spring.profiles.active].yaml
,例如:userservice-dev.yaml -
[spring.application.name].yaml
,例如:userservice.yaml
无论 profile 如何变化,[spring.application.name].yaml 这个文件一定会加载,因此多环境共享配置可写入这个文件。
1. 配置
1. 添加一个环境共享配置
2. 共享配置文件添加上图所示的 属性名(envShardValue),一定要一致,否则无数据
3. 修改端口为 8082 的 profile 值。这样就设置为 UserApplication (8081) 使用的 profile 是 dev,UserApplication2 (8082) 使用的profile是test。
4. 启动 UserApplication:8082 和 UserApplication: 8083
访问 http://localhost:8082/user/prop,结果如下:
访问 http://localhost:8083/user/prop,结果如下:
显然 dev 和 test 两个环境都访问到了 envShardValue 这个共享变量属性。
2. 多种配置优先级
当 nacos 线上配置、本地配置 同时出现时,优先级如下:
[服务名]-[环境].yaml > [服务名].yaml > 本地配置