SpringzCloud之Feign原理

 

目录

Feign是什么

调用原理

加载原理

负载均衡

请求原理


SpringzCloud之Feign原理_第1张图片


Feign是什么

Feign 是一种声明式服务调用组件,它在 RestTemplate 的基础上做了进一步的封装。通过 Feign,我们只需要声明一个接口并通过注解进行简单的配置(类似于 Dao 接口上面的 Mapper 注解一样)即可实现对 HTTP 接口的绑定。
通过 Feign,我们可以像调用本地方法一样来调用远程服务,而完全感觉不到这是在进行远程调用。

Feign 对 Ribbon 进行了集成,利用 Ribbon 维护了一份可用服务清单,并通过 Ribbon 实现了客户端的负载均衡。

调用原理

SpringzCloud之Feign原理_第2张图片

1、在微服务启动时,会向服务发现中心上报自身实例信息,这里ServiceB 包含多个实例 每个实例包括:IP地址、端口号信息。

2、微服务会定期从Nacos Server(服务发现中心)获取服务实例列表。

3、当ServiceA调用ServiceB时,ribbon组件从本地服务实例列表中查找ServiceB的实例,如获取了多个实例如:Instance1、Instance2。这时ribbon会通过用户所配置的负载均衡策略从中选择一个实例。

4、最终,Feign组件会通过ribbon选取的实例发送http请求。

采用Feign+Ribbon的整合方式,是由Feign完成远程调用的整个流程。而Feign集成了Ribbon,Feign使用Ribbon完成调用实例的负载均衡。

Feign远程调用,核心就是通过一系列的封装和处理,将以JAVA注解的方式定义的远程调用API接口,最终转换成HTTP的请求形式,然后将HTTP的请求的响应结果,解码成JAVA Bean,放回给调用者。Feign远程调用的基本流程,大致如下图所示。

å¨è¿éæå¥å¾çæè¿°

从上图可以看到,Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的 Request 请求。通过Feign以及JAVA的动态代理机制,使得Java 开发人员,可以不用通过HTTP框架去封装HTTP请求报文的方式,完成远程服务的HTTP调用。

加载原理

在微服务启动时,Feign会进行包扫描,对加@FeignClient注解的接口,按照注解的规则,创建远程接口的本地JDK Proxy代理实例。然后,将这些本地Proxy代理实例,注入到Spring IOC容器中。当远程接口的方法被调用,由Proxy代理实例去完成真正的远程访问,并且返回结果。

Feign 整体框架非常小巧,在处理请求转换和消息解析的过程中,基本上没什么时间消耗。真正影响性能的,是处理Http请求的环节。

负载均衡

负载均衡就是将网络流量(负载)分摊到不同的网络服务器(可以平均分配,也可以不平均),系统就可以实现服务的水平横向扩展。

那么如果让你设计一个负载均衡组件,你会怎么设计?

 我们需要考虑这几个因素:

  • 如何获取及同步服务器列表?涉及到与注册中心的交互。

  • 如何将负载进行分摊?涉及到分摊策略。

  • 如何将客户端请求进行拦截然后选择服务器进行转发?涉及到请求拦截

 我们从负载均衡的原理 + Ribbon 的架构来学习如何设计一个负载均衡器。

负载均衡也是高可用网络的关键组件:

SpringzCloud之Feign原理_第3张图片

负载均衡的 两个基本点

  • 选择哪个服务器来处理客户端请求。

  • 将客户端请求转发出去。

一个核心原理:通过硬件或软件的方式维护一个服务列表清单。当用户发送请求时,会将请求发送给负载均衡器,然后根据负载均衡算法从可用的服务列表中选出一台服务器的地址,将请求进行转发,完成负载功能。

 负载均衡分类

SpringzCloud之Feign原理_第4张图片

硬件负载均衡 

F5 就是常见的硬件负载均衡产品。

优点:性能稳定,具备很多软件负载均衡不具备的功能,如应用交换,会话交换、状态监控等。

缺点:设备价格昂贵、配置冗余,没有软件负载均衡灵活,不能满足定制化需求。

软件负载均衡

Nginx:性能好,可以负载超过 1W。工作在网络的7层之上,可以针对http应用做一些分流的策略。Nginx也可作为静态网页和图片服务器。Nginx仅能支持http、https和Email协议。

LVS(Linux Virtual Server):是一个虚拟服务器集群系统,采用 IP 地址均衡技术和内容请求分发技术实现负载均衡。接近硬件设备的网络吞吐和连接负载能力。抗负载能力强、是工作在网络4层之上仅作分发之用。自身有完整的双机热备方案,如LVS+Keepalived。软件本身不支持正则表达式处理,不能做动静分离。

服务端负载均衡

Nginx 和 F5 都可以划分到服务端的负载均衡里面,后端的服务器地址列表是存储在后端服务器中或者存在专门的 Nginx 服务器或 F5 上。

服务器的地址列表的来源是通过注册中心或者手动配置的方式来的。

客户端负载均衡

终于轮到 Ribbon 登场了,它属于客户端负载均衡器,客户端自己维护一份服务器的地址列表。这个维护的工作就是由 Ribbon 来干的。

Ribbon 会从 Eureka Server 读取服务信息列表,存储在 Ribbon 中。如果服务器宕机了,Ribbon 会从列表剔除宕机的服务器信息。

Ribbon 有多种负载均衡算法,我们可以自行设定规则从而请求到指定的服务器。

常见的均衡策略如下:

 轮循均衡

权重轮询均衡

随机均衡

Ribbon 核心组件

Ribbon 主要有五大功能组件:ServerList、Rule、Ping、ServerListFilter、ServerListUpdater。

SpringzCloud之Feign原理_第5张图片

负载均衡器 LoadBalancer

用于管理负载均衡的组件。初始化的时候通过加载 YMAL 配置文件创建出来的。

服务列表 ServerList 

ServerList 主要用来获取所有服务的地址信息,并存到本地。

根据获取服务信息的方式不同,又分为静态存储和动态存储。

静态存储:从配置文件中获取服务节点列表并存储到本地。

动态存储:从注册中心获取服务节点列表并存储到本地

服务列表过滤 ServerListFilter

将获取到的服务列表按照过滤规则过滤。

  • 通过 Eureka 的分区规则对服务实例进行过滤。

  • 比较服务实例的通信失败数和并发连接数来剔除不够健康的实例。

  • 根据所属区域过滤出同区域的服务实例。

服务列表更新 ServerListUpdater

服务列表更新就是 Ribbon 会从注册中心获取最新的注册表信息。

心跳检测 Ping

IPing 接口类用来检测哪些服务可用。如果不可用了,就剔除这些服务。

实现类主要有这几个:PingUrl、PingConstant、NoOpPing、DummyPing、NIWSDiscoveryPing。

心跳检测策略对象 IPingStrategy,默认实现是轮询检测。

负载均衡策略 Rule

请求原理

SpringzCloud之Feign原理_第6张图片

第一步:Ribbon 拦截所有标注 @loadBalance 注解的 RestTemplate。RestTemplate 是用来发送 HTTP 请求的。

第二步:将 Ribbon 默认的拦截器 LoadBalancerInterceptor 添加到 RestTemplate 的执行逻辑中,当 RestTemplate 每次发送 HTTP 请求时,都会被 Ribbon 拦截。

第三步:拦截后,Ribbon 会创建一个 ILoadBalancer 实例。

第四步:ILoadBalancer 实例会使用 RibbonClientConfiguration 完成自动配置。就会配置好 IRule,IPing,ServerList。

第五步:Ribbon 会从服务列表中选择一个服务,将请求转发给这个服务。

Feign对Ribbon做了二次封装,实现了内部负载均衡。

你可能感兴趣的:(springclould,java,开发语言)