Nacos注册中心AP架构剖析流程图
2022-09-24 09:52:08 17 举报
nacos-xxx
作者其他创作
大纲/内容
if(instance.isEphemeral()){添加一个延时执行的定时心跳任务BeatTask}
NacosNamingService.getAllInstances()
定时执行任务
将新注册的实例加入对应服务的service的实例列表中去
往阻塞对列tasks里反放入注册实例数据
reqAPI(/instance/list)
@Bean
调用servers实例注销接口HttpMethod.DELETE
serviceManager.removeInstance(
InstanceController.register
PushService.onApplicationEvent()
Spring容器一启动,会将该类的对象放到Spring容器中管理,成为一个bean对象
User
reqAPI(/instance/beat)
serviceInfoMap客户端实例缓存Map
1、name
hostReactor.getServiceInfo
UpdateTask
集群方式暂不讨论
返回的就是注册时写入的实例属性
register()
2000
调用server的服务发现接口HttpMethod.GET传入的参数里面有个客户端的udp端口,这个是方便服务端实例有变化了通过upd方式同步给客户端
Server
HealthCheckReactor.scheduleCheck(clientBeatCheckTask);
定时获取服务端最新服务数据并更新到本地的任务
立即开启一个任务ClientBeatProcessor,更新客户端实例的最后心跳时间
putService(service)
client
源码入口
将注册实例信息更新到注册表内存结构里去
allInstances.addAll(persistentInstances); allInstances.addAll(ephemeralInstances);
将Service放到内层Map中去
将service对应的全量实例instances写到内存注册表中
BeatTask实现了Runable是个线程
instance.setLastBeat(System.currentTimeMillis());
DelegateConsistencyServiceImpl.put
NacosAutoServiceRegistration
AbstractAutoServiceRegistration
service.allIPs
从Nacos官网上找到的客户端发现的代码,这里面先看底层逻辑,实际上服务发现是在第一次调用服务接口时根据服务名去服务端获取。
registerInstance()
继承
NacosRegistration
ephemeralInstances = toUpdateInstances;
lisi
获取客户端的服务实例缓存信息
start()
服务注册
NacosDiscoveryAutoConfiguration
bind(event)
serverProxy.registerService
createEmptyService
reqAPI(/instance/)
ephemeralConsistencyService
将临时的注册实例更新到了cluster的ephemeraInstance属性上去,服务发现临时实例最终从内存里找到的就是这个属性
InstanceController.list
this.serviceRegistry.register(getRegistration())
用一个死循环从阻塞队tasks中拿实例数据处理
DistroConsistencyServiceImpl.init
源码精髓:Nacos合格更新注册表内存方式,为了防止读写并发冲突,大量的运用了CopyOnWrite思想来防止读写并发冲突,具体做法就是把原内存注册表的数据结构拷贝一份,操作完后在最终替换会真正的注册表内存中去。Eureka防止读写并发冲突用的方法是注册表的多级缓存结构,只读缓存,读写缓存,内存注册表,各级缓存之间定时同步,因此客户端感知及时性不如Naccos
service.init()
实现
如果实例不存在重新注册(如网路不通导致实例在服务端被下线或者服务端重启临时实例丢失)
onApplicationEvent
serverProxy.sendBeat(beatInfo)
2、balance
ApplicationListern
deleteIP(instance)
服务发现
如果是临时实例数据
1000
run方法
spring-cloud-alibaba-nacos-discovery.jar里面的spring.factories文件里的NacosDiscoveryAutoConfiguration
调用server的实例发送心跳接口( HttpMethod.PUT)
beatReactor.addBeatInfo
ClientBeatCheckTask
notifyer.run()
service.srvIPs
while(true){tasks.take()}
zhangsan
如果缓存为空,调用server接口,获取最新服务数据
2、同步实例信息到nacos.server集群其它节点
如果某个实例超过30s没有发送心跳服务端直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
实现ApplicationListener接口的类,spring容器启动的时候会调用事件处理方法
udp方式将服务变动通知给订阅客户端
构建双层Map的注册表结构
doSrvIPXT
InstanceController.beat
serviceManager.registerInstance
namingService.registerInstance()
Instance.setHealthy(false)
NacosServiceRegistry
1、将注册实例更新到内存注册表
putServiceAndInit(service)
getPushService().serviceChanged(this);
调用server的实例注册接口(HttpMethod.POST)
源码精髓:很多开源框架为了提升操作性能会大量使用异步任务及内存队列操作,这些操作本身并不需要写入之后立即成功,用这种方式对提升性能有很大操作
service.processClientBeat(clientBeat);
发布服务变化事件
阿里自己内部实现API模式的Distro协议
0 条评论
下一页