nacos_1.14_服务端源码分析
2022-03-30 01:20:33 11 举报
nacos_1.14_服务端源码分析
作者其他创作
大纲/内容
post接口:/nacos/v1/ns/instance
1.将注册实例信息更新到注册表内存结构里
putServiceAndInit(Service service)
如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
/instance/beat
进入
往阻塞队列 queue里放入注册实例数据
raftProxy.proxyPostLarge()
true
notifier.addTask()
源码精髓: nacos这个更新注册表内存方法里,为了防止读写井发冲突,大量的运用了 Coplon Write思想防止井发读写冲突,具体做法就是把原内存结构复制一份,操作完最后再合井回真正的注册表内存里去。Eureka防止读写井发冲突用的方法是注册表的多级鬚存结构,只读存,读写存,内存注册表,各级存之间定时同步,客户端感知的及时性不如 nacos
retrySync(syncTask)
这是注册表结构,他是一个ConcurrentHashMap
获取发送心跳的实例信息
register(HttpServletRequest request)
最后会更新 lasttime为当前时间
keys.add(key)
ephemeralConsistencyService
发布服务变化事件
instance.setLastBeat(System.currentTimeMillis());
InstanceController.list()
如果注册的实例达到一定数量就批量同步给 nacos集群中的其他节点,或者距离上一次节点同步达到一定时间也会开始批量同步
阿里自己实现的CP模式的简单Raft协议
异步任务更新内存注册表
实例是第一次创建
HttpClient.asyncHttpPostLarge()
service.init()
DistroController
服务发现
@PostConstruct
serviceManager.removeInstance()
节点是否是leader
立即开启一个任务Clientbeatprocessor更新客户端实例的最后心跳时间
源码精髓很多开源框架为了提升操作性能会大量使用这种异步任务操作,这些操作本身井不需要写入之后立即成功,用这种方式对提升操作性能有很大帮助
把实例放到内存注册表中
实例初始化
GlobalExecutor.submitDistroNotifyTask(notifier)
queue.offer(key)
HealthCheckReactor.scheduleCheck(clientBeatCheckTask)
putService(service)
同步实例信息给集群其他节点
更新注册实例数据到内存和磁者文件上
GlobalExecutor.submitTaskDispatch(taskScheduler)
TaskScheduler.run()
调用 servere的实例同步接口
如果是持久化实例数据
RaftConsistencyServiceImpl.put()
task.dispatcheraddtask(key)
doSrvIPXT()
判断实例类型
如果同步不成功重试
service.srvIPs
健康检查
GlobalExecutor.submitDataSync()
如果是临时实例数据
同步写实例数据到文件
如果某个实例超过15秒没有收到心跳,则将它的 healthy属性值为 false
ephemeralInstances = toUpdateInstances
AP集群同步
返回的就是注册时写入的实例属性
queue.poll()
源码版本1.1.4
服务心跳
ClientBeatCheckTask
raftStore.write(datum)
将新注册实例加入对应服务servicel的实例列表里去
allInstances.addAll(persistentInstances) allInstances.addAll(ephemeralInstances)
将注册请求转发到集群的leader节点
PersistentConsistencyService
service.processClientBeat(clientBeat);
将注册实例信息更新到注册表内存结构里去
处理实例
执行实例数据批量同步任务
InstanceController.beat()
利用 countdownlatch实现了一个简单的raft协议写入数据的逻辑,必须集群半数以上节点写入成功オ会给客户端返回成功
循环从阻塞队列 tasks里拿实例
如果实例不存在重新注册(如网络不通导致实例在服务端被下线或服务端重启临时实例丢失)
往阻塞队列tasks!里放入注册实例数据
fasle
TaskDispatcher.init()
调用 servert的实例注销接□(httpmethod.delete)
服务注册
mapConsistencyService(key)
Notifier.run()
handle(pair)
实例是否存在
instance.setHealthy(false);
createEmptyService()
2.同步实例信息到 nacos server集群其它节点
将service对应的全量实例instances:写入内存注册表
tasks.take()
开启定时任务
getPushService().serviceChanged(this);
put接口:/distro/datum
/raft/datum/commit
循环从咀塞队列 queue里拿实例数据处理
deleteIp(instance)
serviceManager.registerInstance()
/instance
阿里自己实现的AP模式的 Distro协议
/instance/list
InstanceController.deregister()
将临时的注册实例更新到了 clusters的ephemerallnstances属性上去,发现查找临时实例最终从内存里找到的就是这个属性
serviceManager.getInstance
创建实例
nacos-naming包下的InstanceController
DistroConsistencyServiceImpl.init()
0 条评论
下一页