# 第4节.Nacos的临时实例与持久化实例说明
# 基本说明
当我们使用SpringBoot客户端将服务注册到Nacos的时候,如果没有明确制定指定ephemeral参数的值,默认情况下他是临时实例,即该值默认为true,所有实例的信息都在内存中存储,如果指定该值且值为false,则说明当前需要将实例的注册信息持久化。
临时实例
默认情况,服务实例仅会注册在Nacos内存,不会持久化到Nacos磁盘,其中:
在V1版本时代,其健康检测机制为Client模式,即Client主动向Server上报其健康状态(类似于推模式),默认心跳间隔为5秒,在15秒内Server未收到Client心跳,则会将其标记为“不健康”状态;在30秒内若收到了Client心跳,则重新恢复“健康”状态,否则该实例将从Server端内存清除。即对于不健康的实例,Server会自动清除;
在V2版本时代,由于临时实例采用GRPC的方式,则由服务端主动检查健康状态。
持久实例
服务实例不仅会注册到Nacos内存,同时也会被持久化到Nacos磁盘,其健康检测机制为Server模式,即Server会主动去检测Client的健康状态(类似于拉模式); 默认每20秒检测一次,健康检测失败后服务实例会被标记为“不健康”状态,但不会被清除,因为其是持久化在磁盘的,其对不健康持久实例的清除,需要专门进行;
对于临时实例和持久化实例的存储,Nacos支持用户缓存和文件来存储相关的元数据信息。从作用范围来看,Nacos的元数据大概分为:服务元数据、集群元数据、实例元数据。
# AP模型和CP模型
在Nacos2服务发现的的使用场景下,使用CP模式还是AP模式主要是看服务提供客户端选择,如果服务注册指定为临时,那么走AP模式,否则走CP模式。
AP模式上来就写入,而CP模式则是必须通过Raft算法集群过半节点写入成功之后才写入。在CP模式下,客户端在注册服务信息的同时,对于每个服务会启动一个心跳服务,默认每隔5S时间会发送服务实例的心跳信息。
另外Nacos中不管CP还是AP模式获取服务注册成功都会向ClientServiceIndexesManager和ClientManager写入信息,需要获取某个服务的所有的实例的时候,通过ClientServiceIndexesManager和Service能够获取到所有的该服务实例的clientId,然后通过ClientManager和clientId集合能够获取到该服务所有实例节点信息。
# 元数据字段说明
1、服务的元数据字段
Nacos中通过Service类来定义服务元数据,其中字段如下:
元数据字段 | 字段功能描述 |
---|---|
name | 服务的名称 |
protectThreshold | 保护阈值 |
appName | 服务对应的应用名称 |
groupName | 服务的组名称 |
metadata | 服务的元数据信息 |
clusterMap | 服务的集群列表 |
namespaceId | 服务的命名空间id |
enabled | 服务的开关 |
resetWeight | 重置服务权重的开关 |
owners | 服务的拥有者 |
token | 服务登录需要的token |
ipDeleteTimeout | 实例删除的超时时间,默认30s |
2、实例的元数据字段
Nacos中通过Instance类来定义实例元数据,其中字段如下:
元数据字段 | 字段功能描述 |
---|---|
instanceId | 实例ID |
ip | 实例的IP地址 |
port | 实例的端口号 |
weight | 实例的权重 |
healthy | 实例的健康状态 |
enabled | 实例的开启开关 |
ephemeral | 实例类型,持久化实例还是临时实例 |
clusterName | 实例对应的集群名称 |
serviceName | 实例对应的服务名称 |
metadata | 实例元数据 |
tenant | 实例的租户ID |
lastBeat | 实例的最新的心跳时间 |
3、集群的元数据字段
Nacos中通过Cluster类来定义集群元数据,其中字段如下:
元数据字段 | 字段功能描述 |
---|---|
serviceName | 服务的名称 |
name | 集群的名称 |
healthChecker | 集群的健康检查 |
defaultPort | 默认端口号 |
defaultCheckPort | 默认的检查端口号 |
metadata | 集群的元数据 |
persistentInstances | 持久化的实例列表,HashSet |
ephemeralInstances | 临时的实例列表,HashSet |
service | 集群的服务元数据信息,Service |
# 元数据的存储
service信息存储在ServiceManager中的serviceMap对象中。
在1.x版本:
1、对于临时实例,元数据信息使用DataStore类的内存缓存来存储,本质就是包装了一个Map对象
private Map<String, Datum> dataMap = new ConcurrentHashMap<>(1024);
2、对于持久化实例,元数据信息使用文件方式存储。
在2.x版本:
服务端使用 Client 对象来记录该客户端使用 gRPC 连接发布了哪些服务,又订阅了哪些服务,并将该 Client 进行服务间同步。
1、对于临时实例,元数据信息被转换为InstancePublishInfo信息,并存储Client的模型设计中,核心类为:ClientServiceIndexesManager
protected final ConcurrentHashMap<Service, InstancePublishInfo> publishers = new ConcurrentHashMap<>(16, 0.75f, 1);
2、对于持久化实例,元数据信息使用文件方式存储。