nacos源码解读
2023-06-05 21:14:19 0 举报
nacos源码解读
作者其他创作
大纲/内容
定时获取服务端最新服务数据并更新到本地的任务
/instance
将临时的注册实例更新到了cluster的ephemeralInstances属性上去,服务发现查找临时实例最终从内存里找到的就是这个属性
serviceManager.removeInstance
service.srvIPs
调用server的实例注销接口(HttpMethod.DELETE)
获取客户端的服务实例缓存信息
往阻塞队列tasks里放入注册实例数据
NamingService.registerInstance
GlobalExcutor.submitDistroNotifyTask(notifier)
返回的就是注册时写入的实例属性
NacosServiceRegistry
如果是临时实例数据
service.init()
发布服务变化事件
如果注册的实例达到一定数量就批量同步给nacos集群中的其它节点,或者距离上一次节点同步达到一定时间也会开始批量同步
client
InstanceController.register
instance.setHealthy(false)
service.processClientBeat(clientBeat)
beatReator.addBeatInfo
mapConsistencyService(key)
spring-cloud-alibaba-nacos-discovery.jar里的spring.factories文件里的EnableAutoConfiguration对应NacosDisCoveryAutoConfiguration
ephemeralInstances = toUpdateInstances
TaskDispatcher.init()
serverProxy.registerService
serviceManager.registerInstance
2.同步实例信息到nacos server集群其它节点
UpdateTask
循环从阻塞队列queue里拿实例数据处理
taskScheduler.run()
hostReactor.getServiceInfo
retrySync(syncTask)
GlobalExecutor.submitTaskDispatch(taskScheduler)
getPushService().serviceChanged(this)
putService(service)
ephemeralConsistencyService
将新注册实例加入对应服务service的实例列表里去
循环从阻塞队列tasks里拿实例数据处理
如果实例不存在重新注册(如网络不通导致实例在服务端被下线或服务端重启临时实例丢失)
bind(event)
如果某个实例超过15秒没有收到心跳,则将它的healthy属性置为false
实现
serviceRegistry就是NacosServiceRegistry的实例
源码精髓:很多开源框架为了提升操作性能会大量使用这种异步任务操作,这些操作本身并不需要写入之后立即成功,用这种方式对提升操作性能有很大帮助
HealthCheckReactor.scheduleCheck(clientBeatCheckTask)
如果缓存为空,调用server接口获取最新服务数据
/instance/beat
queue.poll()
1.将注册实例更新到内存注册表
NacosRegistration
notifier.run()
NacosAutoServiceRegistration
register()
@PostConstruct
if (instance.isEphemeral()){添加一个延时执行的定时心跳任务BeatTask}
将service对应的全量实例instances写入内存注册表
BeatTask
调用server的实例同步接口(HttpMethod.PUT)
NacosDiscoveryAutoConfiguration
if (dataSize == partitionConfig.getBatchSyncKeyCount() || (Systm.currentTimeMillis() - lastDispatchTime()) > partitionConfig.getTaskDispatchPeriod())
createEmptyService
taskDispatcher.addTask(key)
DelegateConsistencyServiceImpl.put
定时任务
serviceInfoMap(客户端实力缓存map)
服务注册
deleteIP(instance)
最后会更新lastRefTime为当前时间
GlobalExecutor.submitDataSync
allInstances.addAll(persistentInstances);allInstances.addAll(ephemeralInstances);
serviceRegistry.register(this.getRegistration())
keys.add(key)
InstanceController.beat
延时执行的定时任务更新客户端的服务缓存
执行实例数据批量同步任务
serverProxy.sendBeat(beatInfo)
queue.offer(key)
服务发现
从nacos官方文档上找到的客户端服务发现的代码,这里先看下底层逻辑,实际上,服务发现是在第一次调用服务接口时根据服务名去服务端获取的,这个参看ribbon源码讲解
将注册实例信息更新到注册表内存结构里去
@Bean
如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
NacosNamingService.getAllInstances()
doSrvIPXT
ClientBeatCheckTask
/instance/list
instance.setLastBeat(System.currentTimeMillis())
/distro/datum
如果同步不成功重试
创建内存注册表结构
start()
ApplicationListener
往阻塞队列queue里放入注册实例数据
putServiceAndInit(service)
keys是个list集合,keys存在的原理是避免带宽频繁发请求导致响应时间过长,所以这里采用批量处理的方式发请求,同步集群各节点
AbstractAutoServiceRegistration
InstanceController.list
调用server的实例发送心跳接口(HttpMethod.PUT)
源码精髓:nacos这个更新注册表内存方法里,为了防止读写并发冲突,大量地运用了CopyOnWrite思想防止并发读写冲突,具体做法就是把原内存结构复制一份,操作完最后再合并并替换回真正的注册表内存里去。Eureka防止读写并发冲突用的方法是注册表的多级缓存结构,只读缓存,读写缓存,内存注册表,各级缓存之间定时同步,客户端感知的及时性不如nacos
服务Map
onApplicationEvent
调用server的实例注册接口(HttpMethod.POST)
this.getRegistration()就是NacosRegistration的实例
实现ApplicationListener接口的类,spring容器启动会调用处理时间方法
继承
DistroConsistencyServiceImpl.init()
tasks.take()
接口反馈
阿里自己实现的AP模式的Distro协议
0 条评论
下一页