Hystrix

服务容错保护Hystrix


一、灾难性的雪崩效应

    1.概念:在微服务架构中,一个请求需要调用多个服务是很常见的,如客户端访问A服务,而A服务需要调用B服务,B服务需要调用C服务

草图

    若由于网络原因或者自身的原因,B服务或C服务不能及时响应。A服务将处于阻塞状态,直到B服务和C服务响应,此时若有大量的请求涌入,容器的线程资源会被消耗完毕,导致服务瘫痪。由于服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩效应”

演变过程:微服务系统正常运行
演变过程:微服务系统中某服务忽然收到大量请求
演变过程:高并发导致某服务瘫痪
最后导致整个微服务系统服务宕掉

    2.造成雪崩的原因

        a.服务调用者不可用(硬件故障、程序Bug,缓存击穿、用户当量请求)

        b.重试加大流量(用户重试、代码逻辑重试)

        c.服务调用者不可用(同步等待造成的资源耗尽)

        最终的结果就是—>导致服务不可用,导致服务的一系列不可用,而这种后果往往是无法预料的

    3.解决灾难性雪崩的方式

        a.降级:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回的托底数据,实现一个fallback方法,当请求后端服务出现异常的时候,可以使用fallback方法返回具体的值

        b.隔离(线程池隔离和信号量隔离):限制调用分布式服务的资源使用,式某一个调用的服务出现问题不会影响其他服务的正常调用

        c.熔断:当失败率(如因网络故障/超时造成的失败率高)达到阈(yu)值自动触发降级,熔断器触发的快速失败会进行快速修复

        d.缓存:提供了请求缓存(eg:redis)

        e.请求合并:提供请求合并(多请求合并为单请求)


二、服务降级

        降级:对服务做降级处理

        1.创建项目,配置pom.xml文件,添加SpringCloud依赖,添加Hystrix依赖,添加Eureka依赖(配合服务注册中心解决服务雪崩效应)

pom.xml

        2.修改application.properties/yml全局配置文件,配置应用名,端口,注册中心地址

application.properties/yml

        3.修改服务API,通过@HystrixCommand注解配置托底方法,编写返回托底数据的方法,编写Controller以供访问

Service

        4.修改SpringBoot启动类,开启熔断器

修改启动类

        5.项目结构

项目结构

        @EnableCircuitBreaker注解:一般配合启动类使用,标识开启熔断器

        @HystrixCommand注解(非常重要):与Hystrix解决服务雪崩的方案都需要通过此注解进行相应的配置,可以简单理解为,开启解决雪崩的开关

    什么情况下会触发getFallback的调用:

        1.方法抛出HystrixBadRequestException异常

        2.方法调用超时

        3.熔断器开启拦截调用

        4.线程池/队列/信号量是否跑满


三.1、低版本中的请求缓存

    请求缓存的概念:Hystrix为了降低访问服务的频率,支持将一个请求与返回结果做缓存处理,如果再次请求的URL没有变化,那么Hystrix不会请求服务,而是直接从缓存中将结果返回,这样可以大大降低服务的压力

    Hystrix自带的缓存有两个缺点:

        a.是一个本地缓存,在集群情况下缓存是不能同步的

        b.不支持第三方缓存容器。Redis,memcache不支持,但可以使用Spring的Cache

    由于Spring支持Redis,所以我们这里整合Redis缓存数据库作为请求缓存

    1.安装Redis,

启动Redis

        创建项目,配置pom.xml文件,添加hystirx依赖、添加SpringCache依赖,添加Redis依赖,添加Eureka服务依赖,添加SpringCloud依赖,添加web启动器等

pom.xml

    2.修改application.properteis/yml全局配置文件,配置Redis连接信息,应用名,端口,Eureka服务中心地址等

application.properties/yml

    3.修改Service,配置缓存方法

开启缓存配置
Service

    4.编写Controller以供访问

    5.修改启动类,添加@EnableCacheing注解标识开启缓存,开启Eureka客户端

启动类

    6.项目结构,及测试访问

项目结构

        启动测试:

展示页面
缓存数据中的数据

删除缓存
缓存数据库数据也同步删除

        @CacheConfig注解:开启缓存配置,通过cacheNames属性指定映射的对象(名字可以随意起)

        @CacheEvict注解:添加了@CacheEvice注解的方法可以执行同步删除缓存操作,通过key属性指定参数

        @EnableCaching注解:一般配合启动类使用,标识开启缓存


三、2、高版本中的请求缓存配置

         pom.xml文件中添加Letturce依赖

pom.xml文件中添加Letturce依赖

    application.properties配置文件中的不同

application.properties配置文件

四、请求合并

    简述:请求合并就是将Consumer中一次性(某个时间,eg:10ms内)的所有请求,合并为一次请求,然后调用Provider进行处理

简图

    使用请求合并:

        在微服务架构中,我们将一个项目拆分成很多个独立的模块,这些独立的模块通过远程调用来互相配合工作,但是,在高并发情况下,通信次数的增加会导致总的通信时间增加;

        同时,线程池的资源也是有限的,高并发环境会导致有大量的线程处于等待状态,进而导致响应延迟,为了解决这些问题,我们需要来了解Hystrix的请求合并

    请求合并的缺点:

        使用请求合并之后,本来一个请求可能5ms就搞定了,但是现在需要再等10ms看看还有没有其他的请求一起的,这样一个请求的耗时就从5ms增加到了15ms。不过、如果我们要发起的命令本身就是一个高延迟的命令,那么这个时候就可以使用请求合并了,因为这个时候时间窗的时间消耗就显得微不足道了,另外高并发也是请求合并的一个非常重要的场景


    1.创建项目,配置pom文件,添加hystirx依赖,添加其他依赖等

pom

    2.修改application.properteis/yml配置文件,配置应用名,端口,服务注册中心地址等

application.properteis/yml

    3.修改ProductService

//利用hystrix合并请求

@HystrixCollapser(batchMethod ="batchProduct",

scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,

collapserProperties = {

//请求时间间隔在20ms之内的请求会被合并为一个请求,默认为10ms

        @HystrixProperty(name ="timerDelayInMilliseconds",value ="20"),

//设置触发批处理之前,在批处理中允许的最大请求数

        @HystrixProperty(name ="maxRequestsInBatch",value ="200"),

})

ProductService

    常用的注解

        @HystrixCollapser注解:使用@HystrixCollapser注解开启对某个API的请求合并

        @HystrixProperty注解:设置属性参数,时间间隔、最大请求数等等

        @HystrixCollapser注解中的batchMethod属性:合并请求的方法,方法只能接受一个参数,如果你需要传递多个参数,那么请将他们封装成一个类参数

        @HystrixCollapser注解中的scope属性:设置请求方式,默认为REQUEST

        @HystrixCollapser注解中的timerDelayInMiliseconds属性:设置时间间隔

        @HystrixCollapser注解中的maxRequestsInBatch属性:设置批处理中允许的最大请求数

参数介绍

    4.修改Controller

Controller

    5.项目结构,启动测试

项目结构

        测试结果

测试结果

五、服务熔断

        服务熔断机制相当于电路的跳闸功能

    例如:我们可以配置熔断策略为当请求错误比例在10s>50%时,该服务将进入熔断状态,后续请求都会进入fallback

简图

    1.创建项目,配置pom.xml文件,添加各种依赖

    2.修改application.properties/yml配置文件

    3.修改ProductService

@HystrixCommand(fallbackMethod ="fallback",

commandProperties = {

//默认20个;10内请求数大于20个时就启动熔断器,当请求符合熔断条件时将出发getFallback()

        @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,value ="10"),

//请求错误率大于50%时就熔断,然后for循环发起请求,当请求符合熔断条件时将触发getFallback()

        @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,value ="50"),

//默认5秒;熔断多少秒后去尝试请求

        @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,value ="5000"),

})

Service

    4.编写Controller,修改启动类,使用@EnableCircuitBreaker开启熔断器/断路器,使用@EnableEurekaClient开启Eureka客户端

启动类

        5.项目结构

项目结构

    熔断参数详解:

        circuitBreaker.enabled:是否开启熔断

        circuitBreaker.requestVolumeThreshold:一个统计窗口内熔断触发的最小个数/10s

        circuitBreaker.sleepWindowInMiliseconds:熔断多少秒后去尝试请求

        circuitBreaker.errorThresholdPercentage:失败率达到多少百分比后熔断

        circuitBreaker.forceOpen:是否强制开启熔断

        circuitBreaker.forceClosed:是否强制关闭熔断

熔断参数

六、线程池隔离

    Hystrix处理资源隔离有两种解决方案

        a.线程池隔离    b.信号量隔离

        线程池隔离:线程池隔离将不同的服务调用处理隔离为不同的线程,为这些线程开辟一个独立的、抽象的空间,称为线程池,互不干扰

正常运转图
共同线程池——>瘫痪图
请求——>线程池图
线程池隔离效果图

    线程池隔离优点

        a.使用线程池可以完全隔离依赖的服务,请求线程可以快速放回

        b.当线程池出现问题时,线程池隔离是独立的,不会影响其他服务和接口

        c.当失败的服务再次变得可用时,线程池将清理并立即恢复,而不需要一个长时间的恢复

        d.独立的线程池提高了并发性

    缺点:线程池隔离的主要缺点是他们增加计算开销(CPU)。每个命令的执行涉及到排队、调度和上下文切换且都是在一个单独的线程上运行的

    1.创建项目,配置pom.xml文件,添加各种依赖

pom.xml

    2.配置applicaiton.properties/yml全局文件

applicaiton.properties

    3.修改ProductService

@HystrixCommand(groupKey ="ego-product-provider",

commandKey ="getUsers", threadPoolKey ="ego-product-provider",

threadPoolProperties = {@HystrixProperty(name ="coreSize", value ="30"),//线程池大小

        @HystrixProperty(name ="maxQueueSize", value="100"),//最大队列长度

        @HystrixProperty(name ="keepAliveTimeMinutes", value ="2"),//线程存活时间

        @HystrixProperty(name ="queueSizeRejectionThreshold", value ="15")//拒绝请求

        }, fallbackMethod ="fallback")

ProductService

    4.配置启动类,@EnableCircuitBreaker开启熔断器

启动类
项目结构

    5.启动测试

启动测试

    常用注解各项参数讲解:

        @HystrixCommand注解中的threadPoolProperties属性:配置线程池各项属性

        @HystrixProperty注解:配置详细参数信息

    隔离参数:

        groupKey:服务名(相同服务用一个名称、如商品、用户等等)

        commandKey:接口(服务下面的接口,如购买商品)

        threadPoolkey:线程池的名称:配置全局唯一标识线程池的名称,相同线程池名称的线程池是同一个

        coreSize:线程池大小:这是最大的并发执行数量

        maxQueueSize:最大队列长度:设置BlockingQueue的最大长度

        queueSizeRejectionThreshold:拒绝请求:设置拒绝请求的临界值

        keepAliveTimeMinutes:线程存活时间:设置存活时间,单位分钟

线程池隔离参数

        最后附上Eureka服务注册中心

Eureka服务注册中心

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容