Hystrix在项目中的使用(一)-注解方式

一. 背景

        我们的业务当中会大量依赖于第三方的服务,而这些第三方的服务都是基于Http请求的。我们的调用模式基本如下:

业务时序图

       因此,第三方资源的稳定性会直接影响我们的业务。除此之外,如果是第三方资源响应速度变慢,则会长时间占用我们的线程池,严重的情况下会产生雪崩效应。


外部依赖I发生堵塞


    为了防止这种现象发生,我们需要对服务做隔离,熔断,降级以及限流操作。

二. 业务调用示例

2.1 Controller层

客户端请求地址

2.2 Service业务层

       在service当中使用restTemplate操作第三方资源,在这里我使用restTemplate调用睡眠地址,模拟了一下第三方资源的处理过程。

模拟业务执行10秒
业务调用层

       这里的restTemplate.getForEntity("http://127.0.0.1:8080/hystrix/sleep",String.class)就是在模拟第三方http资源的处理,我们这里是处理10秒。

2.3 客户端调用

      直接使用浏览器访问http://127.0.0.1:8080/hystrix/hystrixTest或是模拟客户端请求


httpClient模拟客户羰
客户端返回结果
浏览器直接访问
服务端调用日志

        以上就是一次正常的服务请求,耗时10S。正是我们模拟的第三方资源处理时间。

三. 模拟在第三方资源处理时间内打爆RestTemplate线程池

3.1 我们将服务端RestTemplate连接池设置为5个

设置RestTemplate线程池数量

3.2 将客户端请求封装的线程中模拟客户端请求

客户端线程模拟调用

3.3 模拟5个客户端并发访问

模拟5个客户端调用
5个客户端返回结果
服务端的日志也均为正常处理1
服务端的日志也均为正常处理2

3.4  模拟6个客户端并发访问,此时我们的并发访问数量超过了线程池设置的5.为了显示,我给线程加了个name 编号


模拟6个客户端并发访问

        通过服务端的日志可以看出,服务端正常接收了来自客户端的6个请求。

服务器输出日志

        但是当调用restTemplate. getForEntity()的时候,由于RestTemplate连接池资源只有5个,所以应该有一个是拿不到线程资源的。

无连接池资源报错
服务端输出日志

        从服务端日志可以看出只有5个完成的调用http请求,其中有一个因为从线程池中拿不到连接而抛出异常。

5个请求正常返回,1个请求发生异常

        这里我们为了演示方便所以6个客户端请求访问的都是同一个资源,在实际生产环境中,6个客户端请求完全可以是访问不同的第三方资源,然后这样就会存在一个问题,当某一个第三方资源发生延时的,后续访问该资源的请求又在不断的请求访问中,导致该资源拿到线程池资源后不能马上释放,但此时其它的第三方服务却是正常的,但是这里线程池中的所有资源已被占用,所以其它的正常访问也因拿不到线程池资源而无法正常访问。这就是我们之前说的雪崩效应。即某一个依赖服务的问题导致整个业务不可用。

四.Hystrix的引用

        我们在项目中引用了Hystrix,Hystrix是用于分布式场景下服务熔断、降级的开源Java库,它的主要作用有,依赖隔离,熔断,降级和监控报警。这里不会过多的介绍Hystrix的概念及定义,具体内容可以看其github网站或是自行搜索,会有大量的仔细介绍。由于Hystrix的原生方式是命令式编程,对原有的业务修改比较大,所以我们这使用的是Hystrix提供的注解方式(hystrix-javanica)

4.1引用hystrix相关依赖

版本号
pom.xml引入Jar包

4.2.Spring中增加Aspect

因为使用的是注解方式,所以我们需要设置Aspect

增加切面 

4.3.修改web.xml

添加监控

五.Hystrix的使用

5.1 业务层增加 @HystrixCommand注解

        这里需要指定超时或是发生异常时执行的方法(executeFallBack),这里需要注意的是,fallbackMethod方法的签名要于业务方法签名一致,否则不会生效。

        使用execution.isolation.thread.timeoutInMilliseconds设置超时时间,业务执行时间超过这个时间则执行fallbackMethod方法并返回客户端。

设置fallback方法及超时时间

5.2 客户端调用

        由于业务执行时间为10S,而我们在Hystrix中设置的为5S,所以会触发服务降级,客户端应该返回fallbackMethod方法的结果

模拟客户端请求
服务端输出

        可以看出客户端接收到的是fallbackMethod方法返回来的结果。但是细心点的人可以看出来,虽然客户端返回以及服务端执行了fallbackMethod方法,但是原有的业务逻辑仍然继续处理完成了。

       因此对于超时的请求,业务不会被中断。当超时引发熔断器启动后,后续一段时间内的请求都将进入fallback,不会再调用业务。

六. 使用Hystrix进行线程隔离

       在上面演示中,我们知道业务在超时的时候会运行fallbackMethod,并将fallbackMethod结果返回给客户端,但是业务并没有发生中断,如果这样的话,大量的客户端进行访问的时候,虽然得到了fallbackMethod返回的结果,但是仍然会点用RestTemplate线程池中的资源,还是会出现雪崩的现象。

       使用Hystrix定义线程池,启到线程隔离的效果。如下图中,定义Hystrix在调用业务时新建线程池的大小为2.为了测试线程隔离的效果,所以让Hystrix的超时间修改为15秒,大于业务处理的时间10S。

定义Hystrix线程池

        新建一个方法来模拟其它的第三方资源,为了方便我们称之前的资源为A资源,新建的这个资源为B资源(hystrixTest2)

B资源请求入口
模拟B资源业务

6.1 模拟4个客户端访问系统资源,其中3个访问A资源一个访问B资源。修改了一个客户端线程,让其访问不同的资源

修改线程方法访问不同资源

        从客户端日志可以看出,访问A资源的3个客户端,有2个成功,1个返回fallback结果,这是因为我们设置的Hystrix的线程池大小为2,所以第三个请求来的时候获取不到可用的线程池资源。而总的restTemplate线程池设置的为5,所以B资源可以继续访问。

客户端访问结果

        再看一下服务端的日志,对B资源访问一次,对A资源访问仅有2次,另一次对A资源的访问因为没有线程资源直接返回fallBack内容。

服务端输出

        通过这种方式,可以起到线程隔离的效果。

线程隔离

七.通过Hystrix做降级操作

        能过上面的演示可知,当业务超时或是无线程池资源时,会调用Hystrix的fallBack方式,因为我们可以在fallBack中处理服务降级逻辑,如

        1.启动限流

        2.页面降级

        3.读写降级

        4.触发开关降级

        5.触发熔断器

八.Hystrix熔断器

       Hystrix本身就提供熔断功能。

       服务的健康状况=请求失败数/请求总数.

       熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值决定的。

熔断开关流程

        每个熔断器默认维护10个bucket,每秒一个bucket,每个bucket记录成功,失败,超时,拒绝的状态,默认为错误超过50%且10秒内超过20个请求进行中断拦截.

修改了requestVolumeThreshold

       也就是说在统计窗口10秒内有至少有2个请求,失败率为50%,即一个失败就发生熔断。

客户端每6秒发起一个请求

模拟4个客户端
服务器结果

        因此,当熔断打开后请求不会发送的业务方法,而是执行快速失败,这样也启到了保护资源的作用。

九.Hystrix DashBoard

       从git下直接下载Hystrix-dashboard,通过gradlew执行

       gitclone https://github.com/Netflix/Hystrix.git

       cd Hystrix/hystrix-dashboard

      ../gradlewappRun


DashBoard

9.1 添加Stream.

        还记得最早在项目web.xml添加的HystrixMetricsStreamServlet吗,就是在此做监控作用的。


http://localhost:8080/hystrix.stream
将此地址添加于stream中



指标说明
DashBoard监控内容

        重新运行一下上面发生熔断的例子,然后再看一下我们的dashboard有什么变化

DashBoard变化过程1
DashBoard变化过程2
DashBoard变化过程3

十. Hystrix 并发控制

        Hystrix还可以对请求的并发量进行控制。


模式修改为信号量 并发数量为3个

        客户端模拟4个并发请求,只有3个是正常返回业务结果,另一个超过了并发数量限量触发了fallback方法��

只有3个请求业务成功

         服务端业务也只是触发了3次,另一次的请求根本就没有请求的业务逻辑

服务端业务只执行了3次

十一. 参考内容

Hystrix配置简单说明(官方文档简译)

Hystrix技术解析(图片版)

使用Hystrix实现自动降级与依赖隔离

Hystrix使用入门手册(中文)

https://github.com/Netflix/Hystrix/wiki/How-it-Works

Hystrix实现自动降级与依赖隔离

防雪崩利器:熔断器 Hystrix 的原理与使用

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,511评论 18 139
  • (git上的源码:https://gitee.com/rain7564/spring_microservices_...
    sprainkle阅读 9,308评论 13 33
  • 一、认识Hystrix Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程池隔离、信号量隔...
    新栋BOOK阅读 26,442评论 1 37
  • 一、认识Hystrix Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程池隔离、信号量隔...
    新栋BOOK阅读 4,002评论 0 19
  • Hystrix使用学习 1. 雪崩效应 一个用户请求处理依赖多个服务,如一个用户请求依赖了服务A,P,H,I,正常...
    酱油和醋阅读 2,124评论 0 2