一、核心架构
Nacos 注册中心包含以下关键组件:
- 服务注册表(Service Registry):存储所有服务实例的元数据(如 IP、端口、健康状态等)。
- 服务提供者(Provider):启动时向 Nacos 注册自己的信息。
- 服务消费者(Consumer):从 Nacos 获取服务实例列表,实现负载均衡调用。
- 健康检查机制:定期检测服务实例可用性,剔除异常实例。
二、服务注册流程
1. 服务提供者注册
-
服务启动后,向 Nacos Server 发送 POST 请求(默认端口 8848),包含:
-
服务名(Service Name)
-
实例 IP 和端口
-
集群名、权重、元数据等
-
-
Nacos Server 将实例信息存入内存注册表 (
ConcurrentHashMap结构),同时写入持久化存储(默认为内嵌 Derby 数据库,支持切换 MySQL)。
2. 注册表结构
Map<String, Map<String, Service>> // 结构示例
- Key: 命名空间(Namespace) -> 服务分组(Group) -> 服务名(Service Name)
- Value: Service 对象(包含集群、实例列表等信息)
三、健康检查与心跳机制
1. 客户端主动上报(默认模式)
-
服务实例定期(默认 5 秒)向 Nacos Server 发送心跳(
/instance/beat)。 -
Nacos Server 收到心跳后,更新该实例的最后健康时间。
-
若 15 秒未收到心跳 ,标记实例为不健康;若 30 秒未收到,直接剔除实例。
2. 服务端主动探测
-
对于非临时实例(
ephemeral=false),Nacos Server 会主动发送 TCP/HTTP 请求进行健康检查。 -
失败多次后移除实例。
四、服务发现与订阅机制
1. 客户端拉取
-
服务消费者启动时,从 Nacos Server 拉取当前服务的实例列表,并缓存在本地。
-
后续通过定时任务(默认 10 秒) 拉取更新。
2. 服务端推送(基于 UDP 或长轮询)
-
Push 模式:Nacos Server 在注册表变更时,通过 UDP 推送更新给订阅的客户端(速度快,但可能丢包)。
-
长轮询(Long-Polling):
-
客户端发起监听请求,若服务无变更,请求挂起(默认 30 秒)。
-
期间若有实例变化(注册/下线),Nacos 立即返回变更数据,客户端更新本地缓存。
-
兼容性和可靠性更高,是默认推荐方式。
五、集群与高可用
1. 分布式一致性协议
-
Nacos 集群采用 Raft 协议 (用于持久化实例数据)和 Distro 协议(临时实例数据同步)。
-
Distro 协议:临时数据每个节点独立处理,通过异步同步保证最终一致性。
-
Raft 协议:确保持久化数据(如配置)的强一致性。
-
2. 节点间数据同步
-
服务注册时,Nacos 节点将数据同步给其他节点(异步批量同步)。
-
客户端默认与一个节点通信,节点故障时自动切换到其他节点。
六、关键特性原理
1. 保护阈值(Protect Threshold)
-
设置比例(如 0~1),当健康实例比例低于阈值时,Nacos 返回全部实例(包括不健康实例),避免雪崩。
-
适用于小规模服务故障时的流量保护。
2. 元数据与权重
-
支持实例打标(元数据),用于灰度发布。
-
权重调整可实现动态流量分配。
3. 持久化 vs 临时实例
-
临时实例(默认):通过心跳维护,异常时自动剔除,适用于云原生场景。
-
持久化实例:需服务端主动健康检查,手动注销,适用于传统架构。
七、与同类组件对比
| 特性 | Nacos | Eureka | Zookeeper |
|---|---|---|---|
| 一致性协议 | Distro(AP)+ Raft(CP) | AP | CP |
| 健康检查 | 心跳/TCP/HTTP/MYSQL | 客户端心跳 | 会话机制 |
| 推送方式 | UDP 推送 + 长轮询 | 客户端定时拉取 | Watch 事件 |
八、总结
Nacos 注册中心的核心原理可归纳为:
- 注册:服务实例通过 REST API 注册到服务端,数据分层存储。
- 健康检查:通过"客户端心跳 + 服务端探测"保证实时性。
- 发现:客户端拉取结合服务端推送,实现高效服务列表同步。
- 一致性:基于 Distro(AP)和 Raft(CP)协议,平衡可用性与一致性。
- 扩展性:支持集群模式、多租户(命名空间)、权重路由等高级特性。
这些设计使 Nacos 在微服务场景中能同时满足高并发、高可用、实时性的需求,成为 Spring Cloud Alibaba 生态的核心组件。