做药物研发的人上什么网站,门户网站建设采购,个人网站psd,企业邮箱域名查询目录 前言
Nacos
如何进行服务自动注册#xff1f;
服务自动注册三板斧
服务实例数据封装--Registration
服务注册--ServiceRegistry
服务自动注册--AutoServiceRegistration
Ribbon
OpenFeign
总结 前言
注册中心要集成SpringCloud#xff0c;想实现SpringCloud的…目录 前言
Nacos
如何进行服务自动注册
服务自动注册三板斧
服务实例数据封装--Registration
服务注册--ServiceRegistry
服务自动注册--AutoServiceRegistration
Ribbon
OpenFeign
总结 前言
注册中心要集成SpringCloud想实现SpringCloud的负载均衡需要实现哪些接口和规范
接下来本文就以探究一下Nacos、OpenFeign、Ribbon、loadbalancer等组件协调工作的原理的方式来讲一讲应该需要是实现哪些接口了。
Nacos
先从Nacos讲起。
Nacos是什么官网中有这么一段话 这一段话说的直白点就是Nacos是一个注册中心和配置中心
在Nacos中有客户端和服务端的这个概念 服务端需要单独部署用来保存服务实例数据的 客户端就是用来跟服务端通信的SDK支持不同语言
当需要向Nacos服务端注册或者获取服务实例数据的时候只需要通过Nacos提供的客户端SDK就可以了就像下面这样
引入依赖
dependencygroupIdcom.alibaba.nacos/groupIdartifactIdnacos-client/artifactIdversion1.4.4/version
/dependency示例代码
Properties properties new Properties();
properties.setProperty(serverAddr, localhost);
properties.setProperty(namespace, 8848);NamingService naming NamingFactory.createNamingService(properties);//服务注册注册一个order服务order服务的ip是192.168.2.100端口8080
naming.registerInstance(order, 192.168.2.100, 8080);//服务发现获取所有的order服务实例
ListInstance instanceList naming.selectInstances(order, true);当服务注册到Nacos服务端的时候在服务端内部会有一个集合去存储服务的信息 这个集合在注册中心界中有个响亮的名字服务注册表。
如何进行服务自动注册
用过SpringCloud的小伙伴肯定知道在项目启动的时候服务能够自动注册到服务注册中心并不需要手动写上面那段代码那么服务自动注册是如何实现的呢
服务自动注册三板斧
SpringCloud本身提供了一套服务自动注册的机制或者说是约束其实就是三个接口只要注册中心实现这些接口就能够在服务启动时自动注册到注册中心而这三个接口我称为服务自动注册三板斧。
服务实例数据封装--Registration
Registration是SpringCloud提供的一个接口继承了ServiceInstance接口 Registration ServiceInstance
从ServiceInstance的接口定义可以看出这是一个服务实例数据的封装比如这个服务的ip是多少端口号是多少。
所以Registration就是当前服务实例数据封装封装了当前服务的所在的机器ip和端口号等信息。
Nacos既然要整合SpringCloud自然而然也实现了这个接口 NacosRegistration
这样当前服务需要被注册到注册中心的信息就封装好了。
服务注册--ServiceRegistry
ServiceRegistry也是个接口泛型就是上面提到的服务实例数据封装的接口 ServiceRegistry
这个接口的作用就是把上面封装的当前服务的数据Registration注册通过register方法注册到注册中心中。
Nacos也实现了这个接口。 NacosServiceRegistry
并且核心的注册方法的实现代码跟前面的demo几乎一样 服务自动注册--AutoServiceRegistration AutoServiceRegistration
AutoServiceRegistration是一个标记接口所以本身没有实际的意义仅仅代表了自动注册的意思。
AutoServiceRegistration有个抽象实现AbstractAutoServiceRegistration AbstractAutoServiceRegistration是个抽象类
AbstractAutoServiceRegistration实现了ApplicationListener监听了WebServerInitializedEvent事件。
WebServerInitializedEvent这个事件是SpringBoot在项目启动时当诸如tomcat这类Web服务启动之后就会发布注意只有在Web环境才会发布这个事件。 ServletWebServerInitializedEvent继承自WebServerInitializedEvent。
所以一旦当SpringBoot项目启动tomcat等web服务器启动成功之后就会触发AbstractAutoServiceRegistration监听器的执行。
最终就会调用ServiceRegistry注册Registration实现服务自动注册 Nacos自然而然也继承了AbstractAutoServiceRegistration NacosAutoServiceRegistration
对于Nacos而言就将当前的服务注册的ip和端口等信息就注册到了Nacos服务注册中心。
所以整个注册流程就可以用这么一张图概括 当然不仅仅是Nacos是这么实现的常见的比如EurekaZookeeper等注册中心在整合SpringCloud都是实现上面的三板斧。 Ribbon
讲完了SpringCloud环境底下是如何自动注册服务到注册中心的下面来讲一讲Ribbon。
我们都知道Ribbon是负载均衡组件他的作用就是从众多的服务实例中根据一定的算法选择一个服务实例。
但是有个疑问服务实例的数据都在注册中心Ribbon是怎么知道的呢
答案其实很简单那就是需要注册中心去主动适配Ribbon只要注册中心去适配了Ribbon那么Ribbon自然而然就知道服务实例的数据了。
Ribbon提供了一个获取服务实例的接口叫ServerList ServerList
接口中提供了两个方法这两个方法在众多的实现中实际是一样的并没有区别。
当Ribbon通过ServerList获取到服务实例数据之后会基于这些数据来做负载均衡的。
Nacos自然而然也实现了ServerList接口为Ribbon提供Nacos注册中心中的服务数据。 NacosServerList
这样Ribbon就能获取到了Nacos服务注册中心的数据。
同样地除了Nacos之外Eureka、Zookeeper等注册中心也都实现了这个接口。 到这其实就明白了Ribbon是如何知道注册中心的数据了需要注册中心来适配。
在这里插个个人的看法其实我觉得Ribbon在适配SpringCloud时对获取服务实例这块支持封装的不太好。
因为SpringCloud本身就是一套约束、规范只要遵守这套规范那么就可以实现各个组件的替换这就是为什么换个注册中心只需要换个依赖改个配置文件就行。 而Ribbon本身是一个具体的负载均衡组件注册中心要想整合SpringCloud还得需要单独去适配Ribbon有点违背了SpringCloud约束的意义。
就类似mybatis一样mybatis依靠jdbc但是mybatis根本不关心哪个数据库实现的jdbc。
真正好的做法是Ribbon去适配SpringCloud时用SpringCloud提供的api去获取服务实例这样不同的注册中心只需要适配这个api无需单独适配Ribbon了。
而SpringCloud实际上是提供了这么一个获取服务实例的apiDiscoveryClient DiscoveryClient
通过DiscoveryClient就能够获取到服务实例当然也是需要不同注册中心的适配。 随着Ribbon等组件停止维护之后SpringCloud官方自己也搞了一个负载均衡组件loadbalancer用来平替Ribbon。
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-loadbalancer/artifactIdversion2.2.5.RELEASE/version
/dependency这个组件底层在获取服务实例的时候就是使用的DiscoveryClient。 所以对于loadbalancer这个负载均衡组价来说注册中心只需要实现DiscoveryClient之后就自然而然适配了loadbalancer。
OpenFeign
OpenFeign是一个rpc框架当我们需要调用远程服务的时候只需要声明个接口就可以远程调用了就像下面这样 听上去很神奇其实本质上就是后面会为接口创建一个动态代理对象解析类上方法上的注解。
当调用方法的时候会根据方法上面的参数拼接一个http请求地址这个地址的格式是这样的http://服务名/接口路径。
比如上面的例子当调用saveOrder方法的时候按照这种规律拼出的地址就是这样的 http://order/order第一个order是服务名第二个order是PostMapping注解上面的。
但是由于只知道需要调用服务的服务名不知道服务的ip和端口还是无法调用远程服务这咋办呢
这时就轮到Ribbon登场了因为Ribbon这个大兄弟知道服务实例的数据。
于是乎OpenFeign就对Ribbon说兄弟你不是可以从注册中心获取到order服务所有服务实例数据么帮我从这些服务实例数据中找一个给我。 于是Ribbon就会从注册中心获取到的服务实例中根据负载均衡策略选择一个服务实例返回给OpenFeign。
OpenFeign拿到了服务实例此时就获取到了服务所在的ip和端口接下来就会重新构建请求路径将路径中的服务名替换成ip和端口代码如下 reconstructURIWithServer Server就是服务实例信息的封装 orignal就是原始的url就是上面提到的http://order/order
假设获取到的orde服务所在的ip和端口分别是192.168.2.100和8080最终重构后的路径就是http://192.168.2.100:8080/order之后OpenFeign就可以发送http请求了。
至于前面提到的loadbalancer其实也是一样的他也会根据负载均衡算法从DiscoveryClient获取到的服务实例中选择一个服务实例给OpenFeign后面也会根据服务实例重构url再发送http请求。 loadbalancer组件重构url代码
总结
到这就把Nacos、OpenFeign、Ribbon、loadbalancer等组件协调工作的原理讲完了其实就是各个组件会预留一些扩展接口这也是很多开源框架都会干的事当第三方框架去适配的只要实现这些接口就可以了。
最后画一张图来总结一下上述组价的工作的原理。 更多资料
关于文章中大家有任何疑问可以通过关注公众号《编程乐学》进行留言同时公众号还有更多有趣的项目以及关于学习编程的笔记资料大家可以看看欢迎大家进行留言。