注册中心要集成 SpringCloud实现负载均衡,需要哪些接口和规范?

news2024/11/24 9:17:34

前几天有个大兄弟问了我一个问题,注册中心要集成SpringCloud,想实现SpringCloud的负载均衡,需要实现哪些接口和规范。

既然这个兄弟问到我了,而我又刚好知道,这不得好好写一篇文章来回答这个问题,虽然在后面的聊天中我已经回答过了。

接下来本文就来探究一下Nacos、OpenFeign、Ribbon、loadbalancer等组件协调工作的原理,知道这些原理之后,就知道应该需要是实现哪些接口了。

Nacos

先从Nacos讲起。

Nacos是什么,官网中有这么一段话

这一段话说的直白点就是Nacos是一个注册中心和配置中心!

在Nacos中有客户端和服务端的这个概念

  • 服务端需要单独部署,用来保存服务实例数据的

  • 客户端就是用来跟服务端通信的SDK,支持不同语言

当需要向Nacos服务端注册或者获取服务实例数据的时候,只需要通过Nacos提供的客户端SDK就可以了,就像下面这样:

引入依赖

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>1.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服务实例
List<Instance> 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是这么实现的,常见的比如Eureka、Zookeeper等注册中心在整合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实际上是提供了这么一个获取服务实例的api,DiscoveryClient

DiscoveryClient

通过DiscoveryClient就能够获取到服务实例,当然也是需要不同注册中心的适配。

随着Ribbon等组件停止维护之后,SpringCloud官方自己也搞了一个负载均衡组件loadbalancer,用来平替Ribbon。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    <version>2.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.1008080,最终重构后的路径就是http://192.168.2.100:8080/order,之后OpenFeign就可以发送http请求了。

至于前面提到的loadbalancer,其实也是一样的,他也会根据负载均衡算法,从DiscoveryClient获取到的服务实例中选择一个服务实例给OpenFeign,后面也会根据服务实例重构url,再发送http请求。

loadbalancer组件重构url代码

相关SpringCloud教程推荐:SpringCloud从入门到精通

总结

到这,就把Nacos、OpenFeign、Ribbon、loadbalancer等组件协调工作的原理讲完了,其实就是各个组件会预留一些扩展接口,这也是很多开源框架都会干的事,当第三方框架去适配的,只要实现这些接口就可以了。

最后画一张图来总结一下上述组价的工作的原理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Omniverse Extensions Command 写在其他.py 文件内 导致找不到Command 无法运行 不生效 的解决方案

提要&#xff1a; Command扩展不在extension.py内 例如我的Command&#xff1a;ScatterCreatePointInstancerCommandLJ 在 commands.py 内 然后使用时报错&#xff1a; 2023-04-10 18:16:11 [Error] [omni.kit.commands.command] Cant execute command: "ScatterCreat…

基于springboot和ajax的简单项目 05 日志界面的查找功能

01.这个是基于input标签的查找功能。 02.修改更新table标签的函数&#xff0c;把username这个参数&#xff0c;加到getjson函数的params中&#xff0c;实现依靠username来查询数据。 var username$("#searchNameId").val();//如下语句的含义是什么&#xff1f;动态在…

STM32F4_PWM输出详解

目录 1. PWM简介 2. PWM原理 3. 定时器PWM输出比较 4. 定时器PWM捕获/比较通道 5. PWM输出相关寄存器 5.1 捕获/比较模式寄存器 TIMx_CCMR1 5.2 捕获/比较使能寄存器 TIMx_CCER 5.3 捕获/比较寄存器 TIMx_CCR1~4 5.4 刹车(断路)和死区寄存器 TIMx_BDTR 6. 库函数配置…

【Python_Scrapy学习笔记(一)】Scrapy框架简介

Scrapy框架简介 前言 Scrapy 框架是一个用 python 实现的为了爬取网站数据、提取数据的应用框架&#xff0c;使用 Twisted 异步网络库来处理网络通讯&#xff0c;可以高效的完成数据爬取。本文主要介绍 Scrapy 框架的构成与工作原理。 正文 1、Scrapy安装 Windows安装&…

【Unity UPR】造个获取深度法线纹理的轮子

描边需要深度法线纹理的加持&#xff0c;效果才能达到最好&#xff0c;但URP下很多版本不支持直接获取_CameraNormalsTexture&#xff0c;而我本人也尝试了一下在12.1.7下偷懒直接拿SSAO里的Depth Normal图&#xff0c; 虽然也能实现吧&#xff0c;但是需要打开SSAO的同时&…

商务接待广州考斯特商务租车详解!

进入四月份以来&#xff0c;全国各个地区都有很多商务活动举办&#xff0c;广州也不例外&#xff0c;广州很多地区都有商务活动的需求。因此不少主办方都需要商务租车来接待客户&#xff0c;而丰田考斯特是市面上常见的一款高端中巴车&#xff0c;主要是因为考斯特的可靠性、安…

【软件设计师13】数据库设计

数据库设计 1. 数据库设计过程 2. E-R模型 3. E-R图向关系模型的转换 例如一对一联系&#xff0c;可以将联系单独做为关系模式&#xff0c;也可以存放到任意一个实体中 而一对多要合并只能合并到多这边&#xff0c;不能存放到1 多对多则联系必须单独转成一个关系模式 4. 案…

赛狐ERP | 亚马逊选品方法与策略详解:如何挑选最优质的产品?

亚马逊作为全球电商巨头&#xff0c;其产品种类之丰富也是无人能及。然而&#xff0c;在如此繁杂的商品体系下&#xff0c;如何选品成为了摆在商家面前的一道难题。本文将从亚马逊选品的目标、方法、策略三个方面进行详细介绍。 一、选品的目标 在进行选择之前&#xff0c;必…

【C语言】位运算 {位运算的应用 :关闭位,判断位,打开位,转置位;位域}

一、基础 参与位运算的对象只能是整型数据(int, unsigned, char)&#xff0c;不能为实型 移位操作符 按位左移n位表示&#xff1a;原数*2^n按位右移n位表示&#xff1a;原数/2^n&#xff08;整除&#xff09;上述运算只适用于左右移位时被溢出舍弃的位不包含1的情况 二、位运…

7.redis-集群

目录 1. 概念 2. 三主三从redis集群配置 3. redis集群读写 4. 主从扩展案例 5.主从降容案例 6.用到的命令 1. 概念 1).分片: 集群中的每个redis实例都被认为是整个数据的一个分片&#xff0c;官方建议是最大1000个 2).槽位: redis集群有16384个哈希槽&#xff0c;每个key…

Mac平台上有哪些好用的常用软件?

我大概分几类给你介绍一下吧。 一、办公类 1.微软的office系列&#xff0c;在mac平台也有office的全家桶&#xff0c;习惯用微软office的也可以安装。 2.wps office&#xff0c;wps可以说是国产最好用的office软件&#xff0c;最重要的是wps可以跨平台&#xff0c;并且云文档…

C/C++程序设计——static关键字

一、修饰局部变量 &#xff08;1&#xff09;称为静态局部变量&#xff0c;改变局部变量的生命周期&#xff0c;生命周期由局部变为全局。 &#xff08;2&#xff09;作用域不发生改变。 &#xff08;3&#xff09;静态局部变量只能被初始化一次。 本质&#xff1a; 改变了局…

获取UNIX系统时间

① 基本认识 UNIX系统时间主要分为两种&#xff1a; 日历时间 和 进程时间 ② 日历时间 该时间是自协调时间时间 1970年1月1日 00:00:00这个特定时间来计算累积的秒数。&#xff08;称为UTC 格林尼治标准时间&#xff09; 时间值是存放在系统类型time_t里面. ③ 进程时间 也称为…

redis哨兵模式配置(配置文件等)

Redis-Sentinel机制主要用三个功能&#xff1a; (1)监控&#xff1a;不停监控Redis主从节点是否安装预期运行 (2)提醒&#xff1a;如果Redis运行出现问题可以 按照配置文件中的配置项 通知客户端或者集群管理员 (3)自动故障转移&#xff1a;当主节点下线之后&#xff0c;哨兵…

OpenGL 简介

OpenGL 简介 GPU 接口规范 对于刚接触 OpenGL 的初学者,常常会有这样一个疑问: OpenGL 的源码在哪里,如何编译? 然而实际上 OpenGL 并不是一个软件实现,更多的是一个标准协议; OpenGL 更像是一种显卡驱动标准,由各个硬件厂家适配,各个硬件厂商根据 OpenGL 接口规范编撰对应的…

【系统集成项目管理工程师】项目进度管理

&#x1f4a5;十大知识领域&#xff1a;项目进度管理 主要考计算题 项目进度管理包括以下 7 个过程: 规划进度管理过程定义活动过程排列活动顺序过程估算活动资源过程估算活动持续时间过程制定进度计划过程控制进度过程 一、规划进度管理过程 制定政策、程序和文档以管理项目进…

亲测:腾讯云轻量应用服务器性能如何?

腾讯云轻量应用服务器性能评测&#xff0c;轻量服务器CPU主频、处理器型号、公网带宽、月流量、Ping值测速、磁盘IO读写及使用限制&#xff0c;轻量应用服务器CPU内存性能和标准型云服务器CVM处于同一水准&#xff0c;所以大家不要担心轻量应用服务器的性能&#xff0c;腾讯云百…

【CSS】13.页面切图和布局实现

页面切图和布局实现 1. 浮动布局 1.1 页面布局 LOGO 部分 NAV 布局 LEFT - SIDEBAR&#xff1a;左边栏布局 CONTENT&#xff1a;内容布局 RIGHT - SIDEBAR&#xff1a;右边栏布局 1.2 流式布局 块的默认布局叫做流式布局 但流式布局并不能满足对页面的需要&#xff0c…

(学习日记)2023.4.10

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

杰林码图像增强算法——超分辨率、图像放大、轮廓和色彩强化算法(二)

一、前言 2023-03-23我发布了基于加权概率模型&#xff08;杰林码的理论模型&#xff09;的图像颜色增强和轮廓预测的应用方法。效果还不太明显&#xff0c;于是我又花了2周的时间进行了技术优化。下面仅提供了x86下的BMP和JPG对应的lib和dll&#xff0c;本文中的算法属于我国…