Hystrix内部提供了两种模式执行逻辑:信号量、线程池。
![cf81020f868862f9c0cd11adc0a2400d.png](https://i-blog.csdnimg.cn/blog_migrate/af0068b3aff8900a9ebccf80041d68a4.jpeg)
默认情况下,Hystrix使用线程池模式。不过两者有什么区别,在实际场景中如何选择?
![ef716f9caf107e65bd888a9144429e40.png](https://i-blog.csdnimg.cn/blog_migrate/4273685ae1e1b0b2ece3be3ada402793.jpeg)
如果要使用信号量模式,需要配置参数execution.isolation.strategy = ExecutionIsolationStrategy.SEMAPHORE.信号量模式在该模式下,接收请求和执行下游依赖在同一个线程内完成,不存在线程上下文切换所带来的性能开销,所以大部分场景应该选择信号量模式,但是在下面这种情况下,信号量模式并非是一个好的选择。比如一个接口中依赖了3个下游:serviceA、serviceB、serviceC,且这3个服务返回的数据互相不依赖,这种情况下如果针对A、B、C的熔断降级使用信号量模式,那么接口耗时就等于请求A、B、C服务耗时的总和,无疑这不是好的方案。另外,为了限制对下游依赖的并发调用量,可以配置Hystrix的execution.isolation.semaphore.maxConcurrentRequests,当并发请求数达到阈值时,请求线程可以快速失败,执行降级。
![8886463715723c88b2688e8e9d6a8416.png](https://i-blog.csdnimg.cn/blog_migrate/2ccb4f4ce2aa56e76f487b13dbccccfb.jpeg)
实现也很简单,一个简单的计数器,当请求进入熔断器时,执行tryAcquire(),计数器加1,结果大于阈值的话,就返回false,发生信号量拒绝事件,执行降级逻辑。当请求离开熔断器时,执行release(),计数器减1。线程池模式在该模式下,用户请求会被提交到各自的线程池中执行,把执行每个下游服务的线程分离,从而达到资源隔离的作用。当线程池来不及处理并且请求队列塞满时,新进来的请求将快速失败,可以避免依赖问题扩散。在信号量模式提到的问题,对所依赖的多个下游服务,通过线程池的异步执行,可以有效的提高接口性能。优势
- 减少所依赖服务发生故障时的影响面,比如ServiceA服务发生异常,导致请求大量超时,对应的线程池被打满,这时并不影响ServiceB、ServiceC的调用。
- 如果接口性能有变动,可以方便的动态调整线程池的参数或者是超时时间,前提是Hystrix参数实现了动态调整。
缺点
- 请求在线程池中执行,肯定会带来任务调度、排队和上下文切换带来的开销。
- 因为涉及到跨线程,那么就存在ThreadLocal数据的传递问题,比如在主线程初始化的ThreadLocal变量,在线程池线程中无法获取
注意因为Hystrix默认使用了线程池模式,所以对于每个Command,在初始化的时候,会创建一个对应的线程池,如果项目中需要进行降级的接口非常多,比如有上百个的话,不太了解Hystrix内部机制的同学,按照默认配置直接使用,可能就会造成线程资源的大量浪费。
今天的分享就到这了,我这里准备了一套java进阶方法笔记,学习资料面试题,电子书等免费笔记供大家学习.需要的小伙伴私信我回复"Java"即可领取免费资料.
![94919c6d9148563bdc9e5f57f61e64db.png](https://i-blog.csdnimg.cn/blog_migrate/612248f7471c2d3354a4c1465cfc75c7.jpeg)
![9530e5a596e0e367161cfff4e0ee2bfd.png](https://i-blog.csdnimg.cn/blog_migrate/bfe868efb8ba53a687350fd428d2c314.jpeg)
![69eed924cace97487c2b7ae50a675129.png](https://i-blog.csdnimg.cn/blog_migrate/f1311699bc3d24c25df389d004fb9c35.jpeg)
java核心知识点
![9cb0fcc625c0a8ae1078bac2abe4f250.png](https://i-blog.csdnimg.cn/blog_migrate/1899d321fff5fe6e91fef28d08640e72.jpeg)