实战系列-Spring Cloud微服务中三把利器Feign、Hystrix、Ribbon

导语
  在之前的分享中分享过关于Fegin的底层实现原理,以及Spring Cloud OpenFegin的启动原理。在这次的分享中主要总结一下Spring Cloud 微服务架构的三把利器。对于Fegin、Hystrix、Ribbon三个组件来说它们之间是什么样的关系。怎么样综合使用等这些问题就是这次分享的内容

文章目录

    • Fegin介绍
    • Ribbon介绍
    • Hystrix介绍
    • 三者关系
    • 如何配置
      • Feign配置说明
      • Hystrix配置说明
      • Ribbon配置说明
    • 总结

Fegin介绍

GitHub地址 https://github.com/OpenFeign/feign.git

  首先通过上次的分析可以知道Fegin是通过Java 语言编写的基于HttpClient的绑定器,在Spring Cloud微服务架构中主要的功能就是实现声明式服务调用。Fegin可以请求其他服务定义的接口,实现服务之间的调用,通过Fegin调用客户端不需要在去编写多余Http请求服务接口,如果在调用过程中出现错误还可以调用其实现类来返回。

  Feign是一个声明式的web service客户端,它使得编写web service客户端更为容易。创建接口,为接口添加注解,即可使用Feign。Feign可以使用Feign注解或者JAX-RS注解,还支持热插拔的编码器和解码器。Spring Cloud为Feign添加了Spring MVC的注解支持,并整合了Ribbon和Eureka来为使用Feign时提供负载均衡。

Ribbon介绍

GitHub地址 https://github.com/Netflix/ribbon.git

  提到Ribbon最常听到的一个名词就是客户端负载均衡,就是说将服务端的负载均衡放到了客户端来实现。对于服务端来说可以启动多个不同端口的实例,通过客户端负载均衡来去调用这些实例。

  Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。提供了客户端组件的一系列完善的配置项,如连接超时,重试等。也就是说通过配置的方式可以列举出需要负载的后端所有的服务,Ribbon会通过对应的策略(轮询、权重、随机等)来去连接这些机器。当然在这些策略与实际业务不符合的时候还可以通过自定义的负载均衡算法来实现调用。因为这些工作都是由客户端来完成,所以被称为是客户端的负载均衡器。

  Ribbon的工作原理,Ribbon工作时分为两步:

  • 第一步 先选择 Eureka Server, 它优先选择在同一个Zone且负载较少的Server;
  • 第二步 再根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址。Ribbon提供了多种策略,例如轮询、随机、根据响应时间加权等

Hystrix介绍

GitHub地址 https://github.com/Netflix/Hystrix.git

  从GitHub地址来看这个也是Netflix的项目,也是由Java来编写 。Hystrix作为熔断流量控制在客户端实现,使用的时候,在方法上进行注解,当请求出错时可以调用注解中的方法返回。
  Hystrix熔断器,容错管理工具,通过熔断机制控制服务和第三方库的节点也就是其他业务之间的调用。从而对延迟和故障提供更强大的容错能力。并且在Spring Cloud Hystrix中实现了线程隔离、断路器等一系列的服务保护功能。它也是基于Netflix的开源框架 Hystrix实现的,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备了服务降级、服务熔断、线程隔离、请求缓存、请求合并以及服务监控等功能。

三者关系

  在开发过程中,如果微服务项目加上了spring-cloud-starter-netflix-hystrix依赖,那么,feign会通过代理模式, 自动将所有的方法用 hystrix 进行包装。在对Feign进行包装的时候也提到过动态代理。

  在Spring Cloud技术体系之下Feign可以提供声明式的服务调用。在这个服务调用的过程中会通过Ribbon从Eureka注册中获取到对应的服务器列表出来,在后续的网络请求调用的过程中Ribbon的作用就是负责整体的负载均衡。将调用通过负载的形式调用到不同的实例上。这也就是实现了Spring Cloud的服务发现以及负载均衡的内容。

  那么在这个过程中好像没有Hystrix的作用。下面就来看看Hystrix的作用,在服务调用的过程中,为了防止因为某些故障而消耗整个服务调用资源,从而导致服务雪崩。所以在服务调用的过程中需要对整个的调用机制有一个熔断的逻辑。整个时候Hystrix就会排上用场。

  调用方会针对被调用微服务设置调用超时时间,一旦超时就会进入熔断逻辑,而这个故障指标信息也会返回给Hystrix组件,Hystrix组件会根据熔断情况判断被调微服务的故障情况从而打开熔断器,之后所有针对该微服务的请求就会直接进入熔断逻辑,直到被调微服务故障恢复,Hystrix断路器关闭为止。

  通过上面的描述就形成了如下的这样一个调用关系图在这里插入图片描述

如何配置

Feign配置说明

  在之前的分享中其实我们知道Feign并不是就简单的实现了一种HttpClient,它提供了很多HttpClient方式,其中最为轻量级的就是OKHTTP的配置。下面这种方式是基于Apache HttpClient的方式来实现的。


feign:
  #替换掉JDK默认HttpURLConnection实现的 Http Client
  httpclient:
    enabled: true
  hystrix:
    enabled: true
  client:
    config:
      default:
       #连接超时时间
        connectTimeout: 5000
       #读取超时时间
        readTimeout: 5000

Hystrix配置说明

  基于整个的Spring Cloud 微服务架构,Hystrix主要的功能是实现微服务之间网络调用故障的熔断、过载保护及资源隔离等。所以提供的配置说明也是关于这些内容的。如果单独使用的话还有其他的配置可以进行自定义。

hystrix:
  propagate:
    request-attribute:
      enabled: true
  command:
    #全局默认配置
    default:
      #线程隔离相关
      execution:
        timeout:
          #是否给方法执行设置超时时间,默认为true。一般我们不要改。
          enabled: true
        isolation:
          #配置请求隔离的方式,这里是默认的线程池方式。还有一种信号量的方式semaphore,使用比较少。
          strategy: threadPool
          thread:
            #方式执行的超时时间,默认为1000毫秒,在实际场景中需要根据情况设置
            timeoutInMilliseconds: 10000
            #发生超时时是否中断方法的执行,默认值为true。不要改。
            interruptOnTimeout: true
            #是否在方法执行被取消时中断方法,默认值为false。没有实际意义,默认就好!
            interruptOnCancel: false
  circuitBreaker:   #熔断器相关配置
    enabled: true   #是否启动熔断器,默认为true,false表示不要引入Hystrix。
    requestVolumeThreshold: 20     #启用熔断器功能窗口时间内的最小请求数,假设我们设置的窗口时间为10秒,
    sleepWindowInMilliseconds: 5000    #所以此配置的作用是指定熔断器打开后多长时间内允许一次请求尝试执行,官方默认配置为5秒。
    errorThresholdPercentage: 50   #窗口时间内超过50%的请求失败后就会打开熔断器将后续请求快速失败掉,默认配置为50

Ribbon配置说明

  Ribbon在Spring Cloud中对于支持微服之间的通信,其主要功能包括客户端负载均衡器及用于中间层通信的客户端。在基于Feign的微服务通信中无论是否开启Hystrix,Ribbon都是必不可少的,Ribbon的配置参数主要如下:

ribbon:
  eager-load:
    enabled: true
  #说明:同一台实例的最大自动重试次数,默认为1次,不包括首次
  MaxAutoRetries: 1
  #说明:要重试的下一个实例的最大数量,默认为1,不包括第一次被调用的实例
  MaxAutoRetriesNextServer: 1
  #说明:是否所有的操作都重试,默认为true
  OkToRetryOnAllOperations: true
  #说明:从注册中心刷新服务器列表信息的时间间隔,默认为2000毫秒,即2秒
  ServerListRefreshInterval: 2000
  #说明:使用Apache HttpClient连接超时时间,单位为毫秒
  ConnectTimeout: 3000
  #说明:使用Apache HttpClient读取的超时时间,单位为毫秒
  ReadTimeout: 3000

注意 :在Spring Cloud中使用Feign进行微服务调用分为两层:Hystrix的调用和Ribbon的调用,Feign自身的配置会被覆盖。
  而如果开启了Hystrix,那么Ribbon的超时时间配置与Hystrix的超时时间配置则存在依赖关系,因为涉及到Ribbon的重试机制,所以一般情况下都是Ribbon的超时时间小于Hystrix的超时时间,否则会出现以下错误:

 o.s.c.n.z.f.r.s.AbstractRibbonCommand - The Hystrix timeout of 10000ms   for the command operation is set lower than the combination of the Ribbon   read and connect timeout, 24000ms.

Ribbon和Hystrix的超时时间配置的关系

  那么Ribbon和Hystrix的超时时间配置的关系具体是什么呢?如下:

Hystrix的超时时间=Ribbon的重试次数(包含首次) * (ribbon.ReadTimeout + ribbon.ConnectTimeout)

而Ribbon的重试次数的计算方式为:

Ribbon重试次数(包含首次)= 1 + ribbon.MaxAutoRetries  +  ribbon.MaxAutoRetriesNextServer  +  (ribbon.MaxAutoRetries * ribbon.MaxAutoRetriesNextServer)

  整个关系可以通过上面那个图来得到。Ribbon的重试次数=1+(1+1+1)=4,所以Hystrix的超时配置应该>=4*(3000+3000)=24000毫秒。在Ribbon超时但Hystrix没有超时的情况下,Ribbon便会采取重试机制;而重试期间如果时间超过了Hystrix的超时配置则会立即被熔断(fallback)。

  如果不配置Ribbon的重试次数,则Ribbon默认会重试一次,加上第一次调用Ribbon,总的的重试次数为2次,以上述配置参数为例,Hystrix超时时间配置为2*6000=12000,

  由于很多情况下,大家一般不会主动配置Ribbon的重试次数,所以做简单说明,以上超时配置的值只是示范,超时配置有点大不太合适实际的线上场景,可以根据实际情况而定。

如果不启用Hystrix,Feign的超时时间则是Ribbon的超时时间,Feign自身的配置也会被覆盖。

总结

  本次分享中最为重要的就是上面那张图,其实配置在需要的时候查询官网或者是百度一下就可以了,实际使用过程中怎么样去配置在理解了原理之后就显得尤为重要了,上面举例子一样,如果不知道图中展示的过程,怎么可以了解整个的调用配置都是什么意思。希望本次总结可以让自己有所提升。

热门文章

暂无图片
编程学习 ·

7 模块与包

7 模块与包 Python中的模块和包一个py文件就是一个模块,py文件的文件名就是模块名。在 Python 里为了对模块分类管理,就需要划分不同的文件夹。多个有联系的模块可以将其放到同一个文件夹下,为了称呼方便,一般把 Python 里的一个代码文件夹称为一个包。7.1 导入模块导入模块…
暂无图片
编程学习 ·

报表热切换是什么意思?如何做到?

热切换(Hot Swap)是指在系统不停机的情况下更换系统部件,在报表业务中则是指在不重启报表及相关应用的情况下完成对报表的维护(新增、修改、删除),冷切换则恰好相反。报表业务很不稳定,业务开展的过程中会刺激出更多查询统计需求,如果每次需求实现后都要等系统空闲(往…
暂无图片
编程学习 ·

3.1.2 Jsoup请求URL

org.jsoup.Jsoup类可以用来处理连接操作。在org.jsoup.Jsoup类中提供了connect(String url)方法来创建一个新连接,该方法的实现依赖于Java网络通信包java.net。在创建连接之后,可通过具体请求方法(GET或POST等)获取URL对应的HTML文件。 如需要采集某页面中的文本内容。首先,…
暂无图片
编程学习 ·

百天打卡计划第四天-Thread之类的加载过程

类的加载过程 类的加载过程一般分为三个大阶段,加载阶段、连接阶段、初始化阶段。 1加载阶段:主要是负责查找并加载类的二进制数据文件,其实就是class文件。 2连接阶段:连接阶段的工作主要分为三个阶段验证:主要是确保类文件的正确性。 准备:为类的静态变量分配内存,并为…
暂无图片
编程学习 ·

MySQL不完全干货教程(持续更新中)

已经有很多教程面面俱到、事无巨细,但实际上能用到的、消化的内容很少。本文聚焦于常见的使用场景,给出MySQL用法和基本原理说明。为便于实践和消化,同时提供了很多案例和脚本。 为了读者进一步深入学习、掌握自我升级的方法,提供了一些权威文档的参考。希望能帮助MySQL初中…
暂无图片
编程学习 ·

半导体物理复习总结(五)——非平衡载流子

非平衡载流子 热平衡状态是指在一定温度下,半导体中的载流子浓度一定。载流子的产生与复合相等,载流子的浓度乘积一定。统一的费米能级是热平衡状态的标志。非平衡状态是指在外界因素的影响下,半导体平衡状态受到微扰,内部的载流子浓度产生涨落。 复合是电子和空穴被洇灭或…
暂无图片
编程学习 ·

ps如何实现阳光照射效果

1.ps打开图片。2.按ctrl+j复制背景图层就会自动创建图层(图层 0 副本),选择图层 0 副本,按ctrl+alt+2调出高光选区,再按ctrl+j复制高光选区就会自动创建图层(图层 1)。3.选择图层1,ctrl+L打开色阶工具,拖动输入色阶的右边白色滑块向左边移动把图中亮的的地方调更亮。4…
暂无图片
编程学习 ·

JVM GC原理

了解JVM GC原理非常重要,对于系统调优非常有用。如果一个系统频繁发生FULL GC,那么会造成系统响应卡顿,更严重的时候会导致系统崩溃。JVM的内存空间 JVM的内存空间,从大的层面上来分析包含:新生代空间(Young)和老年代空间(Old)。新生代空间(Young)又被分为2个部分(Ed…
暂无图片
编程学习 ·

MongoDB安装及服务配置

MongoDB安装官网下载:https://www.mongodb.com/download-center/community----介绍https://www.cnblogs.com/dreamsqin/p/10885038.html 安装到D盘MongoDB目录下,将D:\MongoDB\bin配置到环境变量path下 在MongoDB下创建data、log文件夹 测试MongDB是否安装成功 – 打开cmd命令…
暂无图片
编程学习 ·

二叉搜索树与双向链表

题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 package hk;import java.util.ArrayList;public class Solution {public TreeNode Convert(TreeNode pRootOfTree) {if (pRootOfTree==null){r…
暂无图片
编程学习 ·

vue.js 生命周期(五)

每个vue 实例在被创建时都要经过一系列的初始化过程,例如设置数据监听,编译模板,将实例挂载到DOM并在数据变换时自动更新DOM邓。同时在这过程中会运行一些叫生命周期钩子的函数。 这些函数在vue 实例中 以 属性 : 函数的形式定义。 常用函数: //在实例初始化之后,数据观测…
暂无图片
编程学习 ·

斐波那契数列递归算法的优化

public class Fibonacci { //优化使用的数组 static long[] cach = new long[51];public static void main(String[] args) {long a = System.currentTimeMillis();System.out.println( fd( 50 ) );long l = System.currentTimeMillis();System.out.println( l - a );long l1 =…
暂无图片
编程学习 ·

C#中常见的简答题(第三天)

8.简述ADO.NET中五个主要对象A.Connection:主要是开启程序和数据库之间的连接。没有利用连接对象将数据库打开,是无法从数据库中取得数据的。Close和Dispose的区别,Close以后还可以Open,Dispose以后则不能再用。B.Command:主要可以用来对数据库发出一些指令,例如可以对数据…
暂无图片
编程学习 ·

创新实训—动画小插件开发实践

基于现今动画行业的发展越来越快,为了有效提供动画制作人员的工作效率,许多动画制作软件诸如maya、3d max以及blender越来越注意软件的高效化,无数的插件慢慢地被开发。我们小组使用Python去开发相应的插件,以加快动画制作人员的制作效率1、首先Pyqt的搭建这也是我第一次使…
暂无图片
编程学习 ·

1252 奇数值单元格的数目(模拟)

1. 问题描述:给你一个 n 行 m 列的矩阵,最开始的时候,每个单元格中的值都是 0。另有一个索引数组 indices,indices[i] = [ri, ci] 中的 ri 和 ci 分别表示指定的行和列(从 0 开始编号)。你需要将每对 [ri, ci] 指定的行和列上的所有单元格的值加 1。请你在执行完所有 ind…
暂无图片
编程学习 ·

虚拟养老院,新型养老模式,究竟有什么作用呢?-新导智能

提到“虚拟养老院”很多人是不是榜首想到的是好像黑客帝国相同的“虚拟现实”,难道虚拟养老院是把老人冷冻催眠,然后让他们在-个虚拟的精力世界里边实现养老?其实,虚拟养老院没有这么夸大,它只是基于“居家养老”理念提出的一种利用现代化通讯和服务体系建立的养老模式。在…
暂无图片
编程学习 ·

操作系统-中断

什么是中断?中断是改变处理器执行指令顺序的一种事件。 这样的事件与CPU芯片内外部硬件电路产生的电信号相对应。为什么需要中断?有了中断后,使CPU可以与其他设备并行工作,能有效提高CPU的利用率,改善系统性能,支持系统的异步性。中断的类型 分为 : 同步中断(内部中…
暂无图片
编程学习 ·

java枚举enum

java枚举 jdk5.0之前的 public class SessonTest {public static void main(String[] args) {Seasson spring = Seasson.Spring;System.out.println(spring);} }class Seasson{//1.private final String seassonName;private final String seassonDesc;//2.private Seasson(Str…
暂无图片
编程学习 ·

ChainDesk:深入MSP成员管理与Fabric CA服务实现-走进MSP

目标 MSP 概念及作用MSP 的组成结构MSP 在 Hyperledger Fabric 中的应用任务实现 数据隐私及安全是区块链技术中的的重要组成部分,联盟链中由多个不同的组织组成,且每一个组织又可以由多个节点组成,那么在 Hyperledger Fabric 中使用了什么且如何确保数据隐私及安全,在这一…