nacos服务注册原理源码分析

nacos客户端启动的时候发起服务注册,nacos利用NacosDiscoveryAutoConfiguration类中的NacosAutoServiceRegistration的实例,调用该实例的register注册方法,然后该方法调用的是父类AbstractAutoServiceRegistration的register方法,该方法中serviceRegistry.register方法,封装一个NamingService对象,调用该对象的registerInstance方法,传入服务id和组还有注册实例,如果实例是临时节点(ephemeral),会用线程池创建延时执行的定时心跳任务beatTask,调用方法serverProxy.sendBeat其实是http调用的nacos服务端的rest接口(/instance/beat),参数是:namespceId,serviceName,clusterName,ip,port。然后在调用注册接口,方法是:serverProxy.registerService,调用过得是nacos服务端的/instance 接口,参数是namespceId,serviceName,clusterName,ip,port,healthy等参数。

nacos服务端处理:

nacos服务端获取到客户端发送的注册实例后,register调用serviceManager.registerInstance,该方法里会行执行createEmptyService,根据实例的namespaceId和服务名serviceName和组名groupName初始化一个空的service对象,然后putService到注册表中,该注册表是一个双层map接口的corncurrentMap(Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();),然后对service进行初始化,服务端会创建一个clientBeatCheckTask的定时任务(nacos集群环境下,会对集群数量hash取模,来选择一台服务来执行该任务),每5秒中检查一下客户端是否存活,如果客户端15秒没有收到客户端的心跳,则将healthy属性设置为false,如果在超过30秒没有收到,则直接踢下线客户端,被踢的客户端重启恢复心跳则需要重新注册。

然后调用addInstance将新注册的实例加入到service实例列表中去,distroConsistencyService.put方法里调用onPut方法,这里用了内存队列BlockingQueue处理,来提高并发能力。

然后再从队列中取出来,调用updateIps将实例信息更新到注册表中。然后发布一个服务变化事件,用udp的方式主动推送给nacos服务客户端。nacos是短连接,zookeeper是tcp长连接,这样会节省很多资源,nacos客户端收到udp消息会返回一个ack确认消息,如果nacos服务端在一定时间内没有收到ack,会重发消息,如果超过时间内则不重发。这种方式不能保证nacos客户端及时返现服务实例的变化,但是nacos客户端还有每隔10秒会主动拉取服务注册表,两种方式可以保证客户端对于服务注册列表能搞保证数据不丢失,不过也是保证ap原则。

猜你喜欢

转载自blog.csdn.net/XiWangDeFengChe/article/details/121858161