转自:程铭程铭你快成名

熔断

小铭同学最近正在学Spring Cloud,最近学到熔断这块的知识点,不是很理解,于是请教了公司的大佬老王。

小铭趁空闲时间找到老王:“王哥,我最近在学习Spring Cloud,看到所有书上都说熔断是微服务必须的,可我不用熔断,系统好像也能正常工作。那为什么说它是必须的呢?”

“正常工作是没问题,那发生异常了呢?某个服务挂了或者网络不通的时候会发生什么?”老王反问小铭。

“让我思考一下,如果一个微服务不可用了,那调用它的微服务这个服务就会抛异常,一直到最上层。可这跟熔断又有什么关系?”小铭心中还是有一些疑惑。

老王笑了笑,解释道:“可不只是抛异常怎么简单。在Java中,每一个HTTP请求都会开启一个新线程。而下游服务挂了或者网络不可达,通常线程会阻塞住,直到Timeout。你想想看,如果并发量多一点,这些阻塞的线程就会占用大量的资源,很有可能把自己本身这个微服务所在的机器资源耗尽,导致自己也挂掉。”

小铭有些明白了,追问道:“那是不是最终所有上游微服务都有可能挂掉?”

“是的,这也是称为‘雪崩效应’。最开始是一个微服务挂掉了。随着时间地推移,可能会导致整个系统都不可用。”老王一边回答,一边快速地在电脑上搜出了下面这个图:

“那熔断具体是怎么解决这个问题的?”小铭点点头,然后继续追问。

老王见小铭似乎有些明悟,但知识点还没有串联起来,便一步一步地引导他:“那你知道Spring Cloud断路器的三种状态吗?”

似乎终于到了小铭自己比较熟悉的知识点,自信地说到:“这个我知道,Spring Cloud一般使用Hystrix来做断路器。就跟电路上的闸差不多。它有三种状态:关闭,开启和半开。最开始是关闭状态的,这个时候所有请求都可以通过;如果错误请求达到一定的阈值,就会变成开启状态,就会让所有请求短路,直接返回失败的响应;一段时间后,断路器会变成半开状态,如果下一个请求成功了,就关闭断路器,反之就开启断路器。”

“那这个阈值具体是什么?”

“这里主要就要用到三个属性了:”小铭快速答道

hystrix.command.default.circuitBreaker.requestVolumeThreshold(当在配置时间窗口内达到此数量的失败后,进行短路。默认20个)简言之,10s内请求失败数量达到20个,断路器就会变成打开状态。
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds(短路多久以后开始尝试是否恢复,默认5s)
hystrix.command.default.circuitBreaker.errorThresholdPercentage(出错百分比阈值,当达到此阈值后,开始短路。默认50%)
资源隔离
“非常正确!你知道Hystrix的底层原理吗?”

于是小铭祭出了官方的图:

Hystrix整个工作流如下:

“Hystrix主要使用的是RxJava来做异步请求,RxJava是一个异步框架,是对观察者模式的一个应用。Hystrix会把对每个微服务的请求放到线程池里面,具体分配到哪个线程池可以使用HystrixThreadPoolKey来指定”:

@HystrixCommand(threadPoolKey = "user-hello")
String getUserHello();

老王继续问:“那你知道为什么要有这个key吗?它是用来干嘛的?”小铭摇了摇头,表示自己还不知道。

“你看源码就知道了,Hystrix使用了一个ConcurrentHashMap来保存线程池。”

ConcurrentHashMap<String, HystrixThreadPool> threadPools

小铭心中出现了一个新的问题:那为什么我们需要多个线程池呢?

此时老王继续说道:“这个其实叫资源隔离。应用程序会被完全保护起来,即使依赖的一个服务出问题了,也不会影响到应用程序的其他部分。使用多个线程池就是一种资源隔离方式,也是默认的隔离方式。而且Hystrix底层是使用的RxJava,使用线程池可以让你很方便地实现异步操作。”

“那除了线程池隔离,还有其它隔离方式吗?”

“有的,Hystrix提供了两种隔离方式:线程池隔离和信号量(Semaphore)隔离。”

“是的,线程池隔离就是上面说的那样。信号量主要起一个限流的作用。如果信号量耗尽了,它就直接走fallback流程所以也能防止雪崩。但大多数情况,我们更倾向于使用线程池。”

线程池隔离优缺点
优点:
保护应用程序以免受来自依赖故障的影响,指定依赖线程池饱和不会影响应用程序的其余部分。
当引入新客户端lib时,即使发生问题,也是在本lib中,并不会影响到其他内容。
当依赖从故障恢复正常时,应用程序会立即恢复正常的性能。
当应用程序一些配置参数错误时,线程池的运行状况会很快检测到这一点(通过增加错误,延迟, 超时,拒绝等),同时可以通过动态属性进行实时纠正错误的参数配置。
如果服务的性能有变化,需要实时调整,比如增加或者减少超时时间,更改重试次数,可以通过线 程池指标动态属性修改,而且不会影响到其他调用请求。
除了隔离优势外,hystrix拥有专门的线程池可提供内置的并发功能,使得可以在同步调用之上构 建异步门面(外观模式),为异步编程提供了支持(Hystrix引入了Rxjava异步框架)。
注意:尽管线程池提供了线程隔离,我们的客户端底层代码也必须要有超时设置或响应线程中断,不能 无限制的阻塞以致线程池一直饱和。

缺点:
线程池的主要缺点是增加了计算开销。每个命令的执行都在单独的线程完成,增加了排队、调度和上下文切换的开销。因此,要使用Hystrix,就必须接受它带来的开销,以换取它所提供的好处。
通常情况下,线程池引入的开销足够小,不会有重大的成本或性能影响。但对于一些访问延迟极低的服 务,如只依赖内存缓存,线程池引入的开销就比较明显了,这时候使用线程池隔离技术就不适合了,我 们需要考虑更轻量级的方式,如信号量隔离。
fallback
“刚刚你提到了一个词叫‘fallback流程’?”

“是的,fallback翻译过来是‘回退’的意思,有时候我们也会称它‘服务降级’。”

“那什么时候会触发fallback呢?”

“其实你应该已经可以总结出来了,主要这五种情况会触发fallback:”

执行超时
执行过程抛出异常
断路器打开状态
线程池拒绝(池满后的拒绝策略)
信号量拒绝(信号量耗完)
“那触发fallback后会发生什么?”

老王熟练的打开源码,并快速敲下了一个Demo。“这个你得看HystrixCommand这个类的源码和使用方式。”

class AuthCommand extends HystrixCommand<Boolean> {public Boolean run() {return authService.authenticate(user);}protected Boolean getFallback() {return true;}
}

“我们在使用Hystrix的时候,一般是继承HystrixCommand这个类,重写run和getFallback这两个方法。正常情况它是走run方法的。如果发生了fallback,它就会调用getFallback方法。”

小铭看着这段代码,问到:“这看起来有点麻烦,在Spring Cloud中,有更简单的使用方式吗?”

“当然。在Spring Cloud中,Hystrix可以和OpenFeign无缝集成。OpenFeign接口上的每个方法都会被Hystrix断路器包裹(这也是一种典型的AOP实现)。你可以在注解上配置fallback方法:”

@HystrixCommand(fallbackMethod = "getByIdFallback")
public String getById(String id) {...}private String getByIdFallback(String id) {...}

感觉熔断这一块的知识点差不多理通了,小铭认真道谢,回到自己的位置继续撸代码……

Feign中使用断路器
Feign是自带断路器的,在D版本的Spring Cloud之后,它没有默认打开。需要在配置文件中配置打开它,在配置文件加以下代码:


feign:hystrix:enabled: true

基于service-feign工程进行改造

实现UserClient 接口,并注入到Ioc容器中,代码如下:

@Component
public class UserClientHystrix implements UserClient {@Overridepublic String sayHello(String name) {return "sorry " + name + " 上游服务断开, 服务降级";}@Overridepublic String timeOut() throws InterruptedException {return "链接超时,服务降级";}@Overridepublic String exception() throws Exception {return "发生异常,服务降级";}
}

在FeignClient的UserClient接口的注解中加上fallback的指定类

@FeignClient(value = "service-client", fallback = UserClientHystrix.class)
public interface UserClient {@GetMapping("/client")String sayHello(@RequestParam(value = "name") String name);@GetMapping("/timeOut")String timeOut() throws InterruptedException;@GetMapping("/exception")String exception() throws Exception;
}

启动eureka-server,然后再启动service-client,最后启动service-feign,在浏览器输入http://localhost:8765/sayHello?name=Beck Wang,会看如下效果

接下来我关掉service-client,就会看到如下效果:浏览器上显示了sorry Beck Wang,上游服务断开, 服务降级,就证明我们的熔断器起作用了,否则就会报500。

比较常见的还有timeout,如果上游服务timeout,hystrix也是可以做出处理,首先要配置超时时间

设置超时时间

feign:httpclient:connection-timeout: 5000

还有就是上游服务抛出exception,hystrix也是可以处理

那么熔断之后,到底要怎么做呢?
检查日志,修好它。
fallback就写你业务上可以返回的默认值

原文链接:https://blog.csdn.net/wangchengming1/article/details/93191815

Spring Cloud - 熔断(Hystrix)相关推荐

  1. Spring Cloud中Hystrix、Ribbon及Feign的熔断关系是什么?

    导读 今天和大家聊一聊在Spring Cloud微服务框架实践中,比较核心但是又很容易把人搞得稀里糊涂的一个问题,那就是在Spring Cloud中Hystrix.Ribbon以及Feign它们三者之 ...

  2. Spring Cloud之Hystrix服务容错

    Spring Cloud之Hystrix服务容错 Hystrix的概述 Hystrix的使用 相关依赖 Eureka注册中心 服务提供者 服务消费者 执行测试 @HystrixCommand详解 服务 ...

  3. Spring Cloud Netfix Hystrix(断路器)

    一.灾难性雪崩 造成灾难性雪崩效应的原因,可以简单归结为下述三种: 服务提供者(Application Service)不可用.如:硬件故障.程序BUG.缓存击穿.并发请求量过大等. 重试加大流量.如 ...

  4. Spring Cloud 之 Hystrix

    Spring Cloud 之 Hystrix 1. Feign+Hystrix实现RPC调用保护 2. Spring Cloud Hystrix失败回退 3. Spring Cloud Hystrix ...

  5. Spring Cloud中Hystrix仪表盘与Turbine集群监控

    Hystrix仪表盘,就像汽车的仪表盘实时显示汽车的各项数据一样,Hystrix仪表盘主要用来监控Hystrix的实时运行状态,通过它我们可以看到Hystrix的各项指标信息,从而快速发现系统中存在的 ...

  6. Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失(续)

    前言 上篇文章<Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失>我们对ThreadLocal数据丢失进行了详细的分析,并通过代码的方式复现了这个问题. ...

  7. Spring Cloud中Hystrix的请求合并

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

  8. Spring Cloud中Hystrix仪表盘与Turbine集群监控 1

    Hystrix仪表盘,就像汽车的仪表盘实时显示汽车的各项数据一样,Hystrix仪表盘主要用来监控Hystrix的实时运行状态,通过它我们可以看到Hystrix的各项指标信息,从而快速发现系统中存在的 ...

  9. spring cloud 熔断_Spring Cloud 熔断器/断路器 Hystrix

    在微服务架构中,业务会被拆分成一个个服务,服务间可以彼此调用.为了保证服务的高可用性,单个服务通常会被集群部署,但是由于网络等原因,服务并不能保证100%可用.如果某个服务出现了问题,那么调用这个服务 ...

  10. Spring Cloud之Hystrix

    在微服务架构中,存在那么多的服务单元,若一个单元出现故障(由于网络原因或者自身原因),就很容易因依赖关系而引发故障的蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构更加不稳定.为了解决这样的问题, ...

最新文章

  1. 大脑如何编码视觉信息?动态电极到图像(DETI) 映射技术也许有助于我们揭示其原理...
  2. ITK:对多个线程上的数据进行操作以利用多核处理器
  3. php如何向数组增加数据,php向数组中增加数据的方法是什么
  4. php mysqldb 数据库切换,Python MySQLdb模块连接操作mysql数据库实例
  5. 【struts2】Struts2的运行流程
  6. 服务器水冷冷却系统设计,从三方面设计高效的数据中心冷却系统
  7. C++基础03-C++对c的拓展-函数
  8. 若依前后端分离前端使用Vue3启动教程
  9. 手机怎么安装py thon_Python调试器– Py​​thon pdb
  10. 嵌入式到底应该选择驱动开发,还是应用开发?
  11. 制作PPT怎样设计图片才有观赏性
  12. Co-Grounding Networks with Semantic Attention for Referring Expression Comprehension in Videos
  13. 计算机走进画图世界课件,第一单元走进画图世界.doc
  14. help efun matlab,Matlab优化工具箱在函数最值求解中的应用.pdf
  15. 数据库基础知识:概念篇
  16. 最全Linux面试题
  17. mongodb-18.聚合查询练习1
  18. Linux解决出现错误时蜂鸣器滴滴响的问题
  19. 仿ifeng可翻阅上下滚动新闻
  20. Word版本的毕业论文转成pdf后如何把目录作为书签保存下来

热门文章

  1. win10 dnf服务器未响应怎么办,手把手研习win10系统DNF游戏死机的具体教程
  2. WPS中Excel二维表转一维表
  3. cf进入服务器未响应,win7系统玩cf未响应的解决方法
  4. 如何调整c盘分区大小,怎样把c盘空间调整小些
  5. C++ opencv显示fps帧率
  6. JAVA高级架构师视频课程
  7. 移动硬盘打不开(不用格式化)修复方法
  8. 密码库LibTomCrypt学习记录——(2.13)分组密码算法的工作模式——CCM加密认证模式
  9. underscore.js 964 --- 1103行
  10. 一名数据分析师的工作职责和需要掌握的基本知识