当前位置: 首页 > 后端技术 > Java

面试官:Nacos为什么这么强?说说实现原理?我傻眼了,.

时间:2023-04-01 17:54:59 Java

来源:blog.csdn.net/cold___play/article/details/108032204Nacos架构ProviderAPP:ServiceProviderConsumerAPP:ServiceConsumerNameServer:通过VIP(虚拟IP)或DNS服务路由NacosServer实现Nacos高可用集群:Nacos服务提供者,其中包含的OpenAPI是功能访问入口,ConigService和NamingService是Nacos提供的配置服务和命名服务模块。ConsitencyProtocol是一致性协议,用于实现Nacos集群节点的数据同步。这里使用了Raft算法(Etcd、Redis哨兵选举)。NacosConsole:控制台注册中心原理服务实例在启动时注册到服务注册中心,关闭时,注销服务消费者查询服务注册中心,获取可用实例。服务注册中心需要调用服务实例的健康检查API,验证是否可以处理SpringCloud完成注册的请求。Spring-Cloud-Common包中有一个类org.springframework.cloud.client.serviceregistry.ServiceRegistry,它是SpringCloud提供的服务注册的标准。集成到SpringCloud中实现服务注册的组件都会实现这个接口。该接口的一个实现类是NacoServiceRegistry。SpringCloud集成Nacos的实现过程:自动装配的配置信息包含在spring-clou-commons包的META-INF/spring.factories中如下:其中AutoServiceRegistrationAutoConfiguration是服务注册相关的配置类:在AutoServiceRegistrationAutoConfiguration配置类,可以看到注入了一个AutoServiceRegistration的实例,该类的关系图如下所示。可以看出AbstractAutoServiceRegistration抽象类实现了这个接口,最重要的是NacosAutoServiceRegistration继承了AbstractAutoServiceRegistration。看到EventListener,我们应该知道Nacos是通过Spring的事件机制继承自SpringCloud的。AbstractAutoServiceRegistration实现了onApplicationEvent抽象方法,监听WebServerInitializedEvent事件(Webserver初始化完成后),调用this.bind(event)方法。最后会调用NacosServiceREgistry.register()方法进行服务注册。NacosServiceRegistry在NacosServiceRegistry.registry方法中实现,调用NacosClientSDK中的namingService.registerInstance完成服务注册。跟踪NacosNamingService的registerInstance()方法:通过beatReactor.addBeatInfo()创建心跳信息,实现健康检测。NacosServer必须保证注册的服务实例是健康的,心跳检测就是服务健康检测的手段。serverProxy.registerService()实现服务注册心跳机制:从上面的代码来看,所谓心跳机制就是客户端通过schedule定时的向服务端发送一个数据包,然后启动一个线程不断检测响应服务器。如果没有收到服务器的响应,则认为服务器出现故障。Nacos服务器会根据客户端的心跳包不断更新服务的状态。注册原理:Nacos提供SDK和OpenAPI两种形式实现服务注册。OpenAPI:SDK:这两种形式的本质是一样的,底层都是基于HTTP协议完成请求。所以注册服务就是发送HTTP请求:对于nacos服务器,对外提供的服务接口请求地址为nacos/v1/ns/instance,实现代码在nacos-naming模块下的InstanceController类中:获取serviceName从请求参数(服务名称)和namespaceId(命名空间Id)调用registerInstance注册实例创建一个控制服务(服务信息显示在Nacos控制台“服务列表”),其实就是初始化一个serviceMap,它是一个ConcurrentHashMap集合getService,从serviceMap中根据namespaceId和serviceName获取一个服务对象调用addInstance添加一个服务实例根据namespaceId和serviceName从缓存中获取一个Service实例如果Service实例为空则创建并保存到缓存中使用putService()方法将服务缓存到内存service.init()建立心跳机制consistentService.listen实现数据一致性监控。service.init()方法如下图所示。主要是通过定时任务不断检测当前服务下的所有实例最终发送心跳包的时间。如果超时,则将healthy设置为false以指示服务不健康,并发送服务更改事件。这里请大家思考一个问题,服务实例最后一个心跳包的更新时间会由谁来触发?其实前面说过,Nacos客户端在注册服务的时候也建立了心跳机制。putService方法,其作用是将Service保存到serviceMap中:继续调用addInstance方法将当前注册的服务实例保存到Service中:摘要:Nacos客户端通过OpenAPI发送服务注册请求。Nacos服务器收到请求后,做如下三件事:构建一个Service对象,保存在ConcurrentHashMap集合中使用定时任务,为当前服务下的所有实例建立心跳检测机制根据数据一致性同步服务数据protocol服务提供者地址查询开放API:SDK:InstanceController中的list方法:解析请求参数,通过doSrvIPXT返回服务列表数据根据namespaceId和serviceName获取Service实例根据Service实例获取所有服务提供者实例srvIPs遍历拼接JSON字符串,返回Nacos服务地址动态感知的原理可以通过subscribe方法来实现监听,serviceName表示服务名称,EventListener表示监听的事件:具体调用方式如下:或者调用selectInstance方法,如果subscribe属性设置为true,则监听会自动注册:Nacos客户端中有一个HostReactor类,其作用是实现服务的动态更新。基本原理是:客户端发起定时订阅后,在HostReactor中有一个UpdateTask线程,每10s发送一次Pull请求,获取服务器的最新地址列表。对于服务器来说,它和服务提供者的实例之间维护着心跳检测。服务提供者一旦出现异常,会向Nacos客户端发送Push消息,即服务消费者收到请求后,服务消费者使用HostReactor中提供的processServiceJSON解析消息,并更新本地服务地址列表近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.全球最佳!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!