SpringCloud 服务治理:Nacos
认识 Nacos
Nacos 是阿里巴巴的产品,现在是 SpringCloud 中的一个组件,相比 Eureka 功能更加丰富,在国内受欢迎程度较高。
Nacos 安装
Windows 安装
1)下载解压包
在 Nacos 的 GitHub 页面,提供有下载链接,可以下载编译好的 Nacos 服务端或者源代码:
-
GitHub 主页:https://github.com/alibaba/nacos
-
GitHub 的 Release 下载页:https://github.com/alibaba/nacos/releases
- windows 版本使用 nacos-server-1.4.1.zip 包即可
2)解压
- bin:启动脚本
- conf:配置文件
3)端口配置
-
Nacos 的默认端口是 8848,如果你电脑上的其它进程占用了 8848 端口,请先尝试关闭该进程。
-
如果无法关闭占用 8848 端口的进程,也可以进入 nacos 的 conf 目录,修改配置文件(application.properties)中的端口:
4)启动
进入 bin 目录,以单机模式启动:startup.cmd -m standalone
5)访问 nacos 控制台
在浏览器访问 http://127.0.0.1:8848/nacos ,使用默认的账号和密码(都是 nacos)进行登录。
Linux 安装
Linux 或者 Mac 安装方式与 Windows 类似。
注意 Nacos 依赖于 JDK 运行,所以 Linux 上也需要先安装 JDK。
启动命令:sh startup.sh -m standalone
Nacos 入门案例
-
由于 Nacos 是 SpringCloudAlibaba 的组件,而 SpringCloudAlibaba 也遵循 SpringCloud 中定义的服务注册、服务发现规范。因此使用 Nacos 和使用 Eureka 对于微服务来说,并没有太大区别。主要差异在于依赖不同和服务地址不同。
-
Nacos 客户端实现(服务注册或发现)步骤:
- 引入 nacos.discovery 依赖
- 配置 nacos 注册中心地址:spring.cloud.nacos.server-addr
工程依赖:
-
PS:注释掉 eureka 的依赖。
-
父工程依赖:
<dependencyManagement>
<dependencies>
<!-- spring-cloud-alibaba 管理依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 客户端工程
<!-- nacos 客户端依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置 nacos 注册中心地址:
- PS:注释掉 eureka 的地址。
- 在服务提供方和调用方的 application.yml 中添加:
spring:
cloud:
nacos:
server-addr: localhost:8848
运行:
- 运行微服务后,登录 nacos 管理页面,可以看到微服务信息:
Nacos 服务分级存储模型
Nacos服务分级存储模型:
- 一级是服务(例如 userservice)
- 二级是集群(例如杭州或上海)
- 三级是实例(例如杭州机房的某台部署了 userservice 的服务器)
集群配置
服务跨集群调用问题:
- 服务调用尽可能选择本地集群的服务,跨集群调用延迟较高。
- 本地集群不可访问时,再去访问其它集群。
服务集群属性配置:
- 修改 application.yml:
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos 服务端地址
discovery:
cluster-name: HZ # 配置集群名称,也就是机房位置(例如:HZ,杭州)
- 在 Nacos 控制台可以看到集群变化:
集群负载均衡策略
实现步骤:
1)修改 user-service(服务调用方)集群属性配置,达到以下的效果:
2)修改 order-service(服务提供方)中的 application.yml,设置集群为 HZ:
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos 服务端地址
discovery:
cluster-name: HZ # 配置集群名称,也就是机房位置(HZ,杭州)
3)在 order-service 中设置负载均衡的 IRule 为 NacosRule,这个规则优先会寻找与自己同集群的服务:
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
4)运行效果:
- 优先选择同集群服务实例列表
- 本地集群找不到提供者,才去其它集群寻找,并且会报警告
- 确定了可用实例列表后,再采用随机负载均衡挑选实例
加权负载均衡
实际部署中会出现这样的场景:服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,而我们希望性能好的机器承担更多的用户请求。
为此,Nacos 提供了权重配置来控制访问频率:权重越大则访问频率越高。
- Nacos 控制台可以设置实例的权重值(0~1 之间)。
- 同集群内的多个实例,权重越高被访问的频率越高。
- 权重设置为 0 则完全不会被访问。
实现步骤:
-
在 Nacos 控制台可以设置实例的权重值,首先选中实例后面的编辑按钮:
-
将权重设置为 0.1,测试可以发现 8081 被访问到的频率大大降低:
环境隔离:namespace
Nacos 中服务存储和数据存储的最外层都是一个名为 namespace 的东西,用来做最外层隔离。
- 每个 namespace 都有唯一 id
- 服务设置 namespace 时要写 id 而不是名称
- 不同 namespace 下的服务互相不可见
1)创建 namespace:
-
在 Nacos 控制台可以创建 namespace,用来隔离不同环境:
-
填写命名空间信息:
-
保存后会在控制台看到这个命名空间的 id:
2)修改服务的 namespace:
- 修改 order-service 的 application.yml,添加 namespace:
spring:
datasource:
url: jdbc:mysql://localhost:3306/heima?useSSL=false
username: root
password: 123
driver-class-name: com.mysql.jdbc.Driver
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: SH # 上海
namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空间,填ID
-
重启 order-service 后,再查看控制台:
-
此时 user-service 访问 order-service,因为 namespace 不同,会导致找不到 userservice,控制台会报错:
Nacos 服务治理原理
临时实例和非临时实例
服务注册到 Nacos 时,可以选择注册为临时或非临时实例(通过下面的配置来设置):
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为非临时实例
临时实例宕机时,会从 nacos 的服务列表中剔除,而非临时实例则不会。
Nacos VS Eureka
Nacos 与 Eureka 的共同点
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
Nacos 与 Eureka 的区别
- Nacos 支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式。
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除。
- Nacos 支持服务列表变更的消息推送模式,服务列表更新更及时。
- Nacos 集群默认采用 AP 方式,当集群中存在非临时实例时,采用 CP 模式;而 Eureka 则均采用 AP 方式。