前置准备:
分别提供订单系统(OrderService)和用户系统(UserService)。订单系统主要负责订单相关信息的处理,用户系统主要负责用户相关信息的处理。
一、服务注册与发现
1.1、在父工程当中引入Nacos依赖
<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>
1.2、修改配置文件
cloud:
nacos:
server-addr: localhost:8849 #nacos服务地址
1.3、Nacos服务分级存储
Nacos服务分级存储的主旨是:服务尽可能的调用本地集群提供的服务,跨集群调用延迟较高,本地集群提供的服务不可用时,再去访问其他集群提供的服务。
什么意思呢?看图:
左边为一个集群(HZ),右边也是一个集群(SH),两个集群内部都存在orderService和userService,当某个集群(HZ)的orderService调用userService时,会先查看本集群(HZ)是否提供该服务,提供则直接调用,不提供则调用其它集群(SH)的userService进行远程调用。
如何设置集群属性?
在nacos配置项下面添加如下属性即可
discovery: cluster-name: HZ #集群名称:这里HZ代指杭州
总结:
1.4、NacosRule负载均衡
将orderService注册到HZ集群,userService1和userService2注册到HZ集群,userService3注册到上海集群,按照1.3的描述,orderService会优先调用本集群提供的服务,即userService1和userService2,但是经过测试,在三个userService都无故障的情况下,三个服务都被orderService调用了,这又是为什么?负载均衡规则需要采用NacosRule!
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule #针对某微服务设置其负载均衡规则
NacosRule:优先选择本地集群,再在本机集群采用随机的方式选择服务实例。
1.5、Nacos根据权重负载均衡
说明:刚注册的实例默认权重为1,按照上图,将8081的权重设为0.1,随后使用orderService连续调用userService,两个实例的访问比例就会趋近于权重比值。
小技巧:当我们对某服务进行更新上线时,可以先将更新后的实例权重调成0,进行服务注册后设的较小一些,观察其是否出现BUG等问题,等观察一段时间后发现没有出现什么问题的时候,就可以将该实例的权重调的大一些,将其他实例的权重调的小一些(例如:0),这样做的目的在于逐个实例完成更新,这样就可以实现用户无感知的系统更新。
1.6、Nacos环境隔离
环境隔离的主要作用:将dev、prod、test环境下的服务区分开来。
2.在配置文件当中配置环境ID
在Nacos配置下配置如下属性:
discovery:
namespace: 1bed7a99-086a-4766-a66f-891b508468b7 #指定空间
二、Nacos和Rureka对比
Nacos和Eureka异同:
同:
1、消费者会将拉取到的服务列表缓存到本地,后续使用直接从缓存当中取
2、消费者会定期拉取最新的服务列表(每隔30s)
异:
3、Nacos会把服务的提供者划分为临时实例和非临时实例。
①临时实例:会主动向Nacos发送心跳检测,告知Nacos自己的健康状态,一旦不发了,nacos就会默认你宕机了,就会将你从服务列表剔除。(和Eureka完全一致)
②非临时实例:nacos主动发请求询问非临时实例的健康状态,一旦某天非临时实例真的挂掉了,nacos也不会将他剔除掉,而是将其标记为不健康,等待该实例健康乐再对外提供服务。
4、在消费者拉取玩服务列表的这段时间里,一旦Nacos发现某个服务的实例挂了,nacos会立即将服务列表变更推送给消费者。
如何设置临时实例和非临时实例:
在配置文件的nacos配置当中添加如下属性:
ephemeral: false #是否是临时实例
三、配置中心
3.1、统一配置管理
在以往的开发过程当中,我们习惯性的将系统的配置都写在配置文件当中,一旦某项配置发生变更时,我们以往采取的做法是在配置文件当中逐个进行修改。Nacos提供了配置管理,我们只需要在代码当中获取其配置即可,后续配置信息一旦发生改变,我们也无需在代码层面进行任何修改,而是由nacos告知系统配置发生了改变,并采用新的配置。
3.1.1、新建配置
Data ID:服务名称-配置环境(dev、test、prod).yaml(或properties)
3.1.2、读取Nacos上的配置文件
问题引出及解决:
SpringBoot启动时会先读取Nacos上的配置文件,再读取本地的配置文件,两者进行结合进行使用,我们遇到的问题是什么呢?我们不读取本地配置文件如何知道Nacos的地址呢?SpringBoot有一个比application更优先执行的配置文件-》bootstrap.yml文件,将nacos的地址信息配置在这个文件当中即可。
spring: application: name: userservice #服务名称 profiles: active: dev #环境 cloud: nacos: server-addr: localhost:80 config: file-extension: yaml #文件格式
3.1.3、引入nacos配置管理依赖
<!--nacos配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
3.1.4、从nacos当中读取配置
@Value("${pattern.dateformat}")
public String dateformat;
@GetMapping("/now")
public String now(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.dateformat));
}
3.2、配置热更新
3.3、多环境配置共享
微服务启动时会从nacos读取多个配置文件:
- 【spring.application.name】-【spring.profiles.acive】.yaml(例如:userservice-dev.yaml)
- 【spring.application.name】.yaml(例如:userservice.yaml)
无论profiles如何变化,【spring.application.name】.yaml这个配置文件一定会加载,因此多环境共享配置文件可以写入这个文件。
特殊情况:
1、假设在userservice-dev.yaml和userservice.yaml当中存在相同的配置,那么会读取谁的配置进行使用呢?
结论1:userservice-dev.yaml配置的优先级>userservice.yaml配置的优先级
2、假设在userservice.yaml和本地配置当中也存在相同的配置,又会读取谁的配置进行使用呢?
结论2:userservice.yaml配置的优先级>本地配置的优先级
四、Nacos集群
参考:Nacos集群的搭建过程详解