Nacos 服务注册
# Nacos 服务注册
# 1. 引入依赖
在使用 Nacos 作为注册中心时,我们需要在项目中引入 Spring Cloud Alibaba 的相关依赖。Spring Cloud Alibaba 提供了一系列微服务解决方案,其中包含 Nacos 的服务注册与发现功能。
- 在
cloud-demo父工程的pom.xml文件的<dependencyManagement>中引入 Spring Cloud Alibaba 的依赖:
<!-- Spring Cloud Alibaba 依赖管理,确保子模块中使用的版本一致 -->
<dependencyManagement>
<dependencies>
<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>
</dependencies>
</dependencyManagement>
2
3
4
5
6
7
8
9
10
11
12
说明:通过在父工程中引入
spring-cloud-alibaba-dependencies,可以在子模块中统一管理 Spring Cloud Alibaba 的依赖版本,避免版本冲突。
- 在
user-service和order-service的pom.xml文件中引入 Nacos Discovery 的依赖:
<!-- 引入 Nacos 服务发现依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2
3
4
5
说明:该依赖提供了 Nacos 作为注册中心的功能,使得微服务可以在启动时自动注册到 Nacos 中。
# 2. 配置 Nacos 地址
在 user-service 和 order-service 的 application.yml 中添加 Nacos 服务器地址:
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 指定 Nacos 服务器地址,默认端口为 8848
2
3
4
5
注意:在配置 Nacos 之前,如果你的项目之前使用过 Eureka,需要确保相关的 Eureka 配置被注释或移除,以免冲突。
# 3. 重启服务
完成上述配置后,重启 user-service 和 order-service。你可以通过 Nacos 控制台(http://localhost:8848/nacos)查看服务是否成功注册。

# 4. 保护阈值
在 Nacos 中,可以设置保护阈值,这个值的范围是 0-1 之间的浮点数,它表示当前服务健康实例数与总实例数的比例。
场景说明:
在高并发、大流量场景下,Nacos 作为注册中心,会返回健康的服务实例给消费者。然而,当健康实例数量不足时,可能会导致以下问题:
- 例如,服务 A 有 100 个实例,其中 98 个实例不健康,仅 2 个实例健康。如果 Nacos 只返回这 2 个健康实例,所有请求将集中到这 2 个实例上,最终导致过载并崩溃,进而引发雪崩效应。
保护阈值的作用:
当 (健康实例数 / 总实例数) < 保护阈值 时,Nacos 会将所有实例信息(包括健康和不健康的实例)都返回给消费者。尽管可能会访问到不健康的实例,导致部分请求失败,但这种做法可以防止系统崩溃,避免雪崩效应。
提示:在实际生产环境中,可以根据具体业务场景调整保护阈值,以保证系统稳定性。
# 5. 服务分级存储模型
在微服务架构中,一个服务可以有多个实例。例如 user-service 服务可能有以下几个实例:
- 127.0.0.1:9001
- 127.0.0.1:9002
- 127.0.0.1:9003
- 127.0.0.1:9004
假如这些实例分布在全国不同的机房,例如:
- 127.0.0.1:9001,在上海机房
- 127.0.0.1:9002,在上海机房
- 127.0.0.1:9003,在杭州机房
- 127.0.0.1:9004,在杭州机房
Nacos 会将同一机房内的实例划分为一个集群。因此,user-service 是一个服务,一个服务可以包含多个集群(如杭州、上海),每个集群下有多个实例,形成如下分级模型:

在微服务之间的调用中,应该优先选择访问同集群的实例,因为本地访问的速度更快。当本集群内的实例不可用时,再访问其他集群的实例。例如:

杭州机房的 order-service 应优先访问同机房的 user-service。
# 6. 给 user-service 配置集群
在 user-service 的 application.yml 文件中添加集群配置:
spring:
cloud:
nacos:
server-addr: localhost:8848 # 指定 Nacos 服务器地址
discovery:
cluster-name: HZ # 配置集群名称为 HZ(杭州)
2
3
4
5
6
说明:集群名称用于区分不同的实例组,如不同的机房或数据中心。
重启两个 user-service 实例后,可以在 Nacos 控制台中看到如下结果:

现在,我们再复制一个 user-service 启动配置,并添加新的集群信息:
-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH # 配置端口和集群名称(上海)
启动配置如下图所示:

启动 UserApplication3 后再次查看 Nacos 控制台:

# 7. 同集群优先的负载均衡
默认的 ZoneAvoidanceRule 不能实现根据同集群优先的负载均衡,因此 Nacos 提供了 NacosRule,该规则可以优先从同集群中挑选实例。
# 7.1 给 order-service 配置集群信息
在 order-service 的 application.yml 文件中添加集群配置:
spring:
cloud:
nacos:
server-addr: localhost:8848 # 指定 Nacos 服务器地址
discovery:
cluster-name: HZ # 配置集群名称为 HZ(杭州)
2
3
4
5
6
重点说明:配置集群名称后,
order-service将优先访问集群名称相同的user-service实例。
# 7.2 修改负载均衡规则
在 order-service 的 application.yml 文件中修改负载均衡规则,指定使用 NacosRule:
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 使用 Nacos 提供的同集群优先负载均衡规则
2
3
重点说明:
NacosRule会优先选择与order-service集群相同的user-service实例进行调用,只有在同集群不可用时才会访问其他集群的实例。
以下是关于 Nacos 权重配置和环境隔离的详细总结,包括配置文件中的注释与重点说明,保留了原有的内容与图片。
# 8. 权重配置
在实际生产环境中,服务器设备的性能可能存在差异。例如,部分实例所在机器性能较好,另一些较差。我们希望性能更好的机器能够承担更多的请求。
默认情况下,NacosRule 仅是同集群内随机挑选实例,不会考虑机器性能的差异。因此,Nacos 提供了权重配置,通过调整实例的权重来控制访问频率,权重越大则访问频率越高。
在 Nacos 控制台中,找到 user-service 的实例列表,点击 编辑,即可修改实例的权重:

在弹出的编辑窗口中,可以修改权重:

注意:如果权重修改为
0,则该实例将永远不会被访问。
# 9. 环境隔离
Nacos 提供了命名空间(namespace)来实现环境隔离功能。
- 在 Nacos 中可以创建多个命名空间(namespace)。
- 每个命名空间下可以有不同的分组(group)和服务(service)。
- 不同命名空间之间相互隔离,无法互相访问,例如不同命名空间的服务无法互相发现。

命名空间(Namespace):用于对不同的环境进行隔离,例如开发环境、测试环境和生产环境。
分组(Group):将若干服务或配置归为一组,通常一个项目对应一个分组(如招聘系统、教育系统等)。
服务(Service):指具体的服务实例,例如商品微服务。
配置集(DataId):类似于配置文件的标识,通常用于管理服务的配置信息。
Namespace + Group + Service 结构类似于 Maven 的 GAV 坐标,用于锁定特定服务。
Namespace + Group + DataId 结构类似于 Maven 的 GAV 坐标,用于锁定特定的配置文件。
# 9.1 推荐实践
Nacos 抽象出 Namespace、Group、Service、DataId 等概念,可以根据需求灵活使用。推荐的使用方式如下:
| 概念 | 描述 |
|---|---|
| Namespace | 用于环境隔离,如开发(dev)、测试(test)、生产(prod) |
| Group | 用于项目分组,如某个具体项目 |
| Service | 项目中的某个服务,如用户服务、订单服务 |
| DataId | 项目中的某个配置文件,如数据库配置、缓存配置 |
# 9.2 创建命名空间(Namespace)
默认情况下,所有服务、配置和分组都在同一个命名空间 public 中:

可以点击页面的 新增 按钮,创建一个新的命名空间:

填写表单信息:

创建完成后,可以在页面中看到新的命名空间:

# 9.3 给微服务配置命名空间
给微服务配置命名空间只能通过修改配置文件来实现。
例如,修改 order-service 的 application.yml 文件:
spring:
cloud:
nacos:
server-addr: localhost:8848 # 指定 Nacos 服务器地址
discovery:
cluster-name: HZ # 配置集群名称为 HZ(杭州)
namespace: 6f91682a-dae8-4236-8974-48595037e16c # 配置命名空间的 ID
2
3
4
5
6
7
重点说明:
namespace需要填写命名空间的唯一 ID,而不是名称。
重启 order-service 后,访问 Nacos 控制台,可以看到如下结果:


此时,如果 order-service 和 user-service 不在同一个命名空间,order-service 将无法发现 user-service,控制台会报错,提示找不到服务:

小结
- 命名空间(namespace)用于环境隔离。
- 每个命名空间都有唯一的 ID。
- 不同命名空间下的服务互不可见。
以下是关于 Nacos 与 Eureka 的区别的详细总结,包括配置文件中的注释与重点说明,保留了原有的内容与图片。
# 10. Nacos 与 Eureka 的区别

在 Nacos 中,服务实例分为两种类型:
- 临时实例(默认类型):当实例宕机超过一定时间,会从服务列表中剔除。
- 非临时实例(永久实例):当实例宕机时,不会从服务列表中剔除,而是继续保持注册状态,直到实例恢复正常。
# 1. 配置非临时实例
假设我们希望将 OrderService 配置为非临时实例,而 UserService 继续使用默认配置(临时实例),可以在 application.yml 中进行如下配置:
spring:
cloud:
nacos:
discovery:
ephemeral: false # 将实例设置为非临时实例,默认值是 true(临时实例)
2
3
4
5
重点说明:
ephemeral: false代表非临时实例。当设置为非临时实例时,即使服务宕机,实例依然会保持在注册中心,注册中心会不断主动检测实例状态,直到服务恢复正常。
配置效果如下:



# 2. 临时实例的特点
临时实例的主要特点是,当服务或某个实例出现问题(如宕机或网络异常)时,注册中心会及时将出问题的实例从服务列表中剔除:

# 3. 非临时实例的特点
非临时实例的主要特点是,当服务或某个实例出现问题时,注册中心不会将其剔除,而是保持该实例在服务列表中,注册中心会不断主动检测实例状态,直到问题恢复正常:

# 4. 实例恢复后的行为
无论是临时实例还是非临时实例,只要服务或实例恢复正常,它们都会重新注册到注册中心。
注意:只有 Nacos 注册中心才有临时实例和非临时实例的概念。
# 5. Nacos 与 Eureka 的共同点
- 都支持服务注册和服务拉取。
- 都支持通过服务提供者的心跳机制进行健康检测。
# 6. Nacos 与 Eureka 的区别
服务检测机制:
- Nacos 支持服务端主动检测提供者的状态:
- 临时实例采用心跳模式进行健康检测。
- 非临时实例采用主动检测模式进行健康检测。
- Eureka 仅支持通过心跳机制检测服务健康状态。
- Nacos 支持服务端主动检测提供者的状态:
实例剔除策略:
- 在 Nacos 中:
- 临时实例如果心跳异常,会被从服务列表中剔除。
- 非临时实例即使心跳异常,也不会被剔除,注册中心会持续监控该实例。
- 在 Eureka 中,所有实例都是通过心跳机制检测,异常后会被剔除。
- 在 Nacos 中:
服务列表更新机制:
- Nacos 支持服务列表变更的消息推送模式,服务列表更新更加及时。
- Eureka 采用定期拉取更新的方式,更新可能存在延迟。
集群一致性策略:
- Nacos 集群默认采用 AP 模式,但当存在非临时实例时,会切换为 CP 模式。
- Eureka 始终采用 AP 模式。
