前面我们聊到了 聊一聊nacos是如何进行服务注册的 ,这篇文章我们再来聊一聊nacos是如何整合springcloud的,我们来看一看是如何实现服务的自动注册。
更多技术干货,请扫描下图二维码关注微信公众号。
一、springcloud服务自动注册的三大组件
二、nacos整合springcloud的实现
三、nacos整合ribbon实现
个人的思考
总结
maven依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.2.5.RELEASE
一、springcloud服务自动注册的三大组件
说到springcloud,大家肯定不会陌生,springcloud说的简单点就是提供的一套规范(接口),要想接入springcloud,只要按照这套规范实现接口就能够完成了跟springcloud的整合,比如前几年挺火的springcloud-netflix,现在的springcloud-alibaba,其实都是实现了这套约束。
在服务注册这一方面,springcloud也提供了一套标准,使得项目启动的时候能够自动往服务注册中心注册,nacos就是实现了这套标准,其实不光nacos,什么eureka等实现都是实现了这套标准。接下来就让我看看springcloud提供的这套标准接口。
ServiceRegistry:服务注册接口,通过这个api直接可以向服务注册中心注册
Registration:服务实例的数据的封装,提供获取包括ip、端口之类的服务基本信息的方法
AbstractAutoServiceRegistration:自动注册类,这个类监听了WebServerInitializedEvent事件,容器启动的时候,会发布这个事件,然后触发自动注册
三个组件是如何协同工作的?
我这里先说结论,当容器启动的时候,AbstractAutoServiceRegistration监听到事件,然后调用ServiceRegistry#register方法将Registration(服务实例数据)注册到注册中心。
下面贴出源码
由于监听了事件,所以直接看onApplicationEvent方法的实现就行了
接下来进入start方法
核心就是这个register方法,这个方法就是往服务注册中心进行注册。
这里有两个细节,在注册前后发布了事件,这是个扩展的方式,就是允许你自己在服务注册前后进行自定义的操作。
接下来进入register方法
就是直接调用ServiceRegistry#register方法进行注册。而这些都需要具体的注册中心进行实现。
二、nacos整合springcloud的实现
上面我们说了springcloud提供的关于服务注册的标准,接下来我们就来看看nacos是如何实现的?
在看实现源码之前,我们不防进行猜想,我们来猜一猜nacos怎么实现。其实看源码猜想是个很重要的环节,带着自己的猜想去看验证源码,这样就能够加深印象。
通过上面说的三个组件的工作关系,我们来猜测一下。这三个接口最重要的是服务注册,那么核心是不是ServiceRegistry#register方法实现?Registration只是一个数据的封装,说白了就是跟new出来的User是一样的。那么ServiceRegistry该怎么实现呢?在 聊一聊nacos是如何进行服务注册的 一文中我剖析了,nacos是通过NamingService实现向服务端注册数据的,那么ServiceRegistry的register方法,是不是直接调用NamingService方法实现注册就可以了。接下来我们就来验证一下。
1)ServiceRegistry实现--NacosServiceRegistry
接下来看一看register方法实现。
果然,跟我们猜想的一样,其实就是通过nacos提供的api NamingService将服务实例进行数据进行注册,只不过只是将springcloud的Registration转换成nacos认识的Instance而已。
2)Registration实现 -- NacosRegistration
方法的实现其实就是通过NacosDiscoveryProperties来获取数据的,NacosDiscoveryProperties就是我们在application配置文件配置的属性的封装对象。
3)AbstractAutoServiceRegistration继承 -- NacosAutoServiceRegistration
nacos的实现重写了springcloud提供的register方法,我们看一下重写的方法
其实就是加了一些判断,最终还是调用父类的register方法,也就是调用ServiceRegistry#register方法。
上面这三个实现是通过自动装配来实现对象的构造,附上配置类NacosServiceRegistryAutoConfiguration,方便大家查看关系
三、nacos整合ribbon实现
首先抛出个问题,为什么nacos需要整合ribbon?
ribbon是负载均衡的组件,负载均衡,那是不是得有服务列表,不然怎么实现负载均衡?是的,基于这个原因,就可以解释nacos为什么需要适配ribbon,因为通过nacos提供的api,就可以从nacos服务端拉取服务注册表,这样服务数据的来源就有了。那么nacos是如何整合ribbon的呢?
ribbon提供了一个接口ServerList,ribbon会通过这个接口获取服务数据,nacos就是通过实现这个接口来实现整合nacos的。
ServerList 源码
就是提供了两个获取服务实例的方法。
接下来我们来看一看ServerList的实现NacosServerList源码。
可以看出,实现其实很简单,就是通过nacos提供的api NamingService来实现获取服务实例,然后转换成ribbon认识的NacosServer。
如果不清楚NamingService api的作用,请看一下 聊一聊nacos是如何进行服务注册的 这篇文章。
NacosServerList对象构造源码
个人的思考
其实ribbon在整合springcloud的实现在获取服务数据的整合方式我其实是持保留意见的。因为ribbon并没有实现通过springcloud提供的api来获取服务列表,而是需要第三方注册中心来主动适配ribbon,这就使得springcloud失去了约束的意义。就类似mybatis一样,mybatis依靠jdbc,但是mybatis根本不关心哪个数据库实现的jdbc。其实ribbon完全可以通过springcloud的api(DiscoveryClient)来实现从获取列表,这样注册中心主要去适配这个接口,而不需要直接适配ribbon。
DiscoveryClient其实就是springcloud提供的一个接口,用来获取服务实例的,需要各自注册中心实现,nacos的实现是NacosDiscoveryClient,实现也跟上面整合ribbon的差不多,这里我就不去翻源码了。
如果你有兴趣,可以仿照nacos实现,自己实现ribbon通过DiscoveryClient来获取服务实例。这里我就不贴出实现的源码,如果你有需要,可关注公众号,回复 ribbon,即可获取到实现源码和使用方法。
总结
本文首先讲了springcloud的关于服务自动注册的三大组件,通过这些组件就实现了当web应用启动的时候自动往服务注册中心进行注册,接下来我们剖析了nacos对应三大组件实现的源码,然后讲解了nacos适配ribbon的源码,同时个人也提出了ribbon实现springcloud的获取服务列表的看法。最后谢谢大家。
PS:如果觉得这篇文章对你有帮助,欢迎评论、收藏、点赞;如果想获得更多技术干货,请关注公众号,感谢支持。