Nacos源码-小结
Posted IT-熊猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nacos源码-小结相关的知识,希望对你有一定的参考价值。
文章目录
核心功能点
【1】服务注册:Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。
【2】服务心跳:在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。
【3】服务同步:Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性。
【4】服务发现:服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时会在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存
【5】服务健康检查:Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false(客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
源码精髓总结
1】注册表的结构说明(这个仅是记录):
//Map<namespaceId, Map<service_name, Service>【ConcurrentSkipListMap】>
private final Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();
//再分析里面的Service,Map<clusterName, Cluster>
private Map<String, Cluster> clusterMap = new HashMap<>();
//再分析Cluster
private Set<Instance> persistentInstances = new HashSet<>();
private Set<Instance> ephemeralInstances = new HashSet<>();
【2】分析注册表为何要这么设计
1.注册表是基于第一层ConcurrentHashMap,第二层ConcurrentSkipListMap,第三层HashMap,然后定位到对应的Cluster。
2.至于为什么要这样设计,一方面是将粒度划分的更细,通过源码分析可知,nacos更新注册表是进行小范围的更新,如定位到Cluster的临时列表ephemeralInstances或者持久列表persistentInstances【这两个都是set集合,所以排除了会有重复的数据】。因为粒度小所以更新速度会更快。
3.其次采用的是 写时复制思想,也就是说,不会影响读取的效率,因为是新开一个副本,将新旧的数据合并到一个新数据里面,然后将引用指向新数据。
4.其次是为了高扩展,对namespace进行划分【对开发环境隔离】,对service进行划分【对服务进行隔离】,对Cluster进行划分【多机房部署,加快访问速度】
5.为了解决并发读写问题,采用的是ConcurrentHashMap与ConcurrentSkipListMap的分段锁,加上Cluster里面的写时复制。其次Cluster里面是不加锁的,因为是单线程进行修改,不存在冲突。
6.虽说牺牲了,一定的实时性,但是大大提高了并发的性能。
【3】分析AP架构下为什么高性能的原因
1.因为采用的是异步任务加队列的形式来实现注册的,所以响应很快,然后任务是慢慢做的。
2.Notifier 是在DistroConsistencyServiceImpl类中初始化,默认单线程,而且队列为ArrayBlockingQueue<>(1024 * 1024)。
3.缩小了变更数据的粒度,单线程避免了线程安全问题【不用加锁】。
4.这种方式毫无疑问是会存在问题的,就是响应了但是没有注册上。但是对于这个问题,在客户端里面做了心跳机制,如果检测不到会重新注册。
【4】分析Nacos为什么感知快的原因
采用的是客户端定时进行一次拉取,兼服务端采用异步的形式使用UDP发送更新的数据到客户端;
虽然UDP存在通知丢失的情况,但是每隔1s的拉取依旧能很好的保持数据的最终一致性。
健康检查
//Nacos的健康检测有两种模式:
//临时实例:
采用客户端心跳检测模式,心跳周期5秒
心跳间隔超过15秒则标记为不健康
心跳间隔超过30秒则从服务列表删除
//永久实例:
采用服务端主动健康检测方式
周期为2000 + 5000毫秒内的随机数
检测异常只会标记为不健康,不会删除
以上是关于Nacos源码-小结的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud微服务:阿里开源组件Nacos,服务和配置管理