Nacos注册中心临时实例(AP)与持久实例(CP)

2025-06-26 14:54
847
0

CAP理论可以查看我的另一篇文章:《分布式系列:分布式相关概念介绍》

Nacos 作为注册中心时,支持 AP(可用性和分区容错性)与 CP(一致性和分区容错性)模式的切换,这使其能根据不同业务场景需求灵活调整架构特性。

一、简单介绍AP与CP模式

  • 1、AP 模式(默认)
    • 核心特性:强调服务的可用性和分区容错性,在网络分区等故障时仍能保证服务注册与发现的可用性,但可能出现短暂的数据不一致。
    • 支持注册临时实例(ephemeral=true)
    • 实现方式:
      • 基于Distro 协议进行分片与异步同步:按哈希将服务实例分片到不同节点.
      • 写操作先更新本地内存(ConcurrentHashMap ),再通过异步任务广播给其他节点,保证最终一致。
      • 适用于对服务可用性要求高、允许短暂数据不一致的场景(如电商、流量高峰业务)。
  • 2、CP 模式
    • 核心特性:强调数据的强一致性和分区容错性,在网络分区时会牺牲部分可用性,确保所有节点数据一致。
    •  支持注册持久化实例(ephemeral=false)
    • 实现方式:
      • 基于Raft 算法实现强一致性
      • 所有写操作需多数节点确认后才生效,读操作直接从主节点获取,确保数据一致。
      • 适用于对数据一致性要求高的场景(如金融交易、订单系统)。

注意:

  • 临时实例和持久化实例的区别主要在健康检查失败后的表现,持久化实例健康检查失败后会被标记为不健康,而临时实例会直接从列表删除。
  • 实例的临时性(ephemeral)是在注册实例时指定的属性,与服务端的CP/AP模式并不是强绑定的关系。一个服务中可以同时存在临时实例和持久化实例。

二、AP/CP模式配置

如果要进行CP模式配置,最好修改下Nacos服务端配置文件,其中的raft相关配置进行设置,如下为raft相关配置示例:

# 选举超时时间设置为5秒,避免网络抖动导致频繁选举
nacos.core.protocol.raft.data.election_timeout_ms=5000

# 快照间隔设置为1小时,平衡性能和数据安全
nacos.core.protocol.raft.data.snapshot_interval_secs=3600

# 根据CPU核心数适当调整工作线程数
nacos.core.protocol.raft.data.core_thread_num=16
nacos.core.protocol.raft.data.cli_service_thread_num=8

# 使用安全的线性读策略
nacos.core.protocol.raft.data.read_index_type=ReadOnlySafe

# RPC超时时间适当调大,避免网络波动影响
nacos.core.protocol.raft.data.rpc_request_timeout_ms=10000

# 启用数据安全保障
nacos.core.protocol.raft.data.sync=true

# 开启pipeline优化提升性能
nacos.core.protocol.raft.data.replicator_pipeline=true

# 适当增加buffer大小提升性能
nacos.core.protocol.raft.data.disruptor_buffer_size=32768

1、在SpringBoot项目客户端配置

SpringBoot项目可以通过以下方式可以切换注册实例为AP还是CP:

# application.yml
spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        # 通过ephemeral属性来控制是临时实例(AP)还是持久化实例(CP)
        ephemeral: false  # false表示CP模式,true表示AP模式(默认)

2、通过API方式注册客户端实例

@Service
public class ServiceRegistration {
    @NacosInjected
    private NamingService namingService;
    
    public void registerService() throws NacosException {
        Instance instance = new Instance();
        instance.setIp("192.168.1.1");
        instance.setPort(8080);
        instance.setEphemeral(false);  // 是否是临时实例
        instance.setWeight(1.0);       // 实例权重
        instance.setClusterName("DEFAULT"); // 集群名
        
        namingService.registerInstance("service-name", instance);
    }
}

最佳实践建议

  • 对于大多数微服务场景,推荐使用默认的AP模式,因为服务发现对可用性的要求通常高于一致性
  • 如果业务对数据一致性有强要求,可以使用持久化实例(ephemeral=false)
  • 避免频繁切换CP/AP模式,应该在系统设计阶段就确定好适合的模式
  • 可以在同一个服务中混合使用临时实例和持久化实例,以满足不同实例的一致性需求

三、附录

《官方文档,Nacos1.0.0发布支持ephemeral字段说明》

《官方文档,注册实例的参数介绍》

 

 

全部评论