AP 和 CP 模式

Nacos 是一个偏向 AP(可用性 + 分区容忍性) 的分布式系统,但它同时也提供了一定的 CP(一致性 + 分区容忍性) 的能力,具体取决于使用的模式:

  • Nacos 1.x 默认使用 AP 模型,使用 内嵌数据库(如 Derby)或 MySQL 作为数据存储。服务注册信息是以 最终一致性(eventual consistency) 为目标,强调高可用性。注册中心挂掉某些节点不会影响读写,牺牲了强一致性。
  • Nacos 2.x 引入 CP 特性(如使用 Raft),支持多集群部署,尤其在配置管理和某些服务注册场景中,引入了 Raft 协议 来保证强一致性(CP 模型)。可以配置为更偏向 CP(如注册信息同步一致等)。

Nacos 本身没有一个统一的“开关”来直接切换 AP 和 CP 模式,但它确实提供了一些机制来在不同场景中选择偏 AP 还是偏 CP 的一致性策略,尤其是在 Nacos 2.x 版本之后可以通过是否启用 Raft 模式来实现一致性切换

✅ 启用 CP 模式(仅限配置管理):在 Nacos 2.x 中,可以使用 nacos.core.auth.enabled 等配置项来控制集群行为,但一致性相关的关键机制是在 NacosCluster.conf 或类似配置中指定:

serverMode: standalone | cluster
dataConsistency: embedded | raft
  • dataConsistency: embedded ➜ 普通模式(偏AP)
  • dataConsistency: raft ➜ 使用 Raft 保证配置的强一致性(偏CP)

Nacos 是一个“默认偏向 AP、部分场景可支持 CP”的系统。使用 Nacos 2.x 并开启 Raft 模式时,某些核心功能(如配置中心)可以达到 CP 级别的一致性保障。

临时节点和永久节点

类型 是否自动过期 使用场景 注册方式 存储一致性 默认值
临时节点 ✅ 会过期 动态服务(如微服务实例) 默认注册方式 偏AP ✅ 是默认
永久节点 ❌ 不过期 静态服务或第三方服务 需要手动配置 偏CP ❌ 需配置

临时节点(ephemeral = true)是默认行为,通常用于 应用启动时动态注册 的服务实例(如 Spring Cloud 微服务)。如果客户端断开连接(如宕机、网络中断),服务会自动从注册中心移除。实现机制基于 心跳机制。适合自动化的弹性伸缩场景。

永久节点(ephemeral = false)需要显式指定,即使客户端断开连接,服务也不会自动移除,必须手动下线。适用于一些 不支持心跳 或不希望被自动摘除的服务,例如:第三方服务、某些长生命周期系统服务、也可以提高一致性保障(偏向 CP 模型)。

心跳机制

  1. 客户端主动发送心跳(默认 5 秒一次,支持配置)。
  2. 服务端维护每个临时实例的“最后一次心跳时间”。
  3. 如果超过一定时间未收到心跳(默认 15 秒,称为“临界超时时间”),则认为实例不可用。
  4. 超时的实例会被自动从注册中心移除

如果 Nacos 宕机,依赖它的微服务还能不能成功启动?

当 Nacos 同时作为 注册中心配置中心 时,如果 Nacos 服务宕机了,那么是否还能成功启动依赖它的微服务,取决于使用的是注册功能还是配置功能。

作为注册中心时,如果 Nacos 服务宕机新启动的微服务无法注册到 Nacos,因为没有可用的注册中心。但微服务本身仍然可以启动成功,只是在注册时会报错(除非你配置了启动失败策略,如 spring.cloud.nacos.discovery.fail-fast=true)。如果配置了自动退出策略,服务可能会因为注册失败而停止运行。已注册的微服务间通信不受影响,因为客户端(如 Spring Cloud)有本地缓存机制,可短时间内维持调用。

作为配置中心时,如果 Nacos 宕机,首次启动服务时是否能启动成功,取决于配置的加载方式,若使用的是 spring.cloud.nacos.config.fail-fast=true(默认是 false),那么启动时如果无法从 Nacos 加载配置,服务会启动失败。若是 fail-fast=false,那么:如果本地有配置的缓存(默认在 /data/nacos/config),则可以从缓存中读取并启动成功;如果无缓存,则启动失败。

可以配置持久化使得 Nacos 的配置信息(如 Data ID、Group、配置内容)不仅保存在内存或临时文件中,而是持久化存储到数据库中,以防止 Nacos 宕机或重启时配置丢失。

动态配置管理

例如你在 Nacos 中有一个配置:

user:
  name: zhangsan

Spring Boot 微服务启动后读取了这个配置。

当你在 Nacos 控制台把它改成:

user:
  name: lisi

如果项目正确开启了配置刷新:

  • 微服务无需重启
  • 配置会自动推送到客户端
  • Bean 中读取到的新值立即生效

关键点:@RefreshScope
想让 Bean 支持动态刷新,需要:

@RefreshScope
@RestController
public class UserController {

    @Value("${user.name}")
    private String name;

    @GetMapping("/name")
    public String name() {
        return name;
    }
}

这里:

  • @RefreshScope
    表示这个 Bean 可以在配置变更时重新实例化
  • Nacos 配置变化后,会自动刷新 Bean

Nacos 配置刷新原理(简化)
Nacos Client 会:

  1. 长轮询监听配置
  2. 服务端配置变化
  3. 推送变更通知
  4. Spring Context 发布 RefreshEvent
  5. @RefreshScope Bean 重新创建

所以整个过程:

  • 不重启 JVM
  • 不重启 Spring Boot
  • 只是局部 Bean 刷新

配置自动刷新是否默认开启?
新版 Spring Cloud Alibaba 中:

spring:
  cloud:
    nacos:
      config:
        refresh-enabled: true

通常默认就是开启的。

但 Bean 仍然需要:

@RefreshScope

否则读取到的值可能不会更新。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐