Hystrix 隔离策略:线程池、信号量
记一次被问到的面试题:Hystrix系列之信号量、线程池
Hystrix内部,提供了两种模式隔离策略:信号量
、线程池
。(默认情况下,Hystrix使用 线程池模式
。)
- 信号量隔离,适应非网络请求,因为是同步的请求,无法支持超时,只能依靠协议本身
- 线程池隔离,即:每个实例都增加个线程池进行隔离
总结:
对信号量 Semaphore 还不了解的,来这里瞅瞅了解一下哈:Java并发工具类 Semaphore 的用法
线程池隔离 | 信号量隔离 | |
---|---|---|
是否支持超时 | 支持,超时直接返回 | 不支持,如果阻塞,只能通过调 用协议(如:socket超时才能返回) |
是否支持熔断 | 支持,当线程池到达maxSize后,再 请求会触发fallback接口进行熔断 |
支持,当信号量达到maxConcurrentRequests 后,再请求会触发fallback |
隔离原理 | 每个服务单独用线程池 | 通过信号量的计数器 |
是否是异步调用 | 可以是异步,也可以是同步。看调用的方法 | 同步调用,不支持异步 |
资源消耗情况 | 大,大量线程的上下文切换,容易造成机器负载高 | 小,只是个计数器 |
官网介绍
官网地址:https://github.com/Netflix/Hystrix/wiki/Configuration#execution.isolation.strategy
This property indicates which isolation strategy HystrixCommand.run() executes with, one of the following two choices:
-
THREAD
— it executes on a separate thread and concurrent requests are limited by the number of threads in the thread-pool -
SEMAPHORE
— it executes on the calling thread and concurrent requests are limited by the semaphore count
信号量隔离:
它在调用线程上执行,并发请求受到信号量的限制。
每次调用线程,当前请求通过计算信号量进行限制,当信号量大于了最大请求数(maxConcurrentRequests)时,进行限制,调用fallback接口快速返回。
最重要的是,信号量的调用是同步的
,也就是说,每次调用都会阻塞调用方的线程,直到结果返回
。这样就导致了无法对访问做超时(只能依靠调用协议超时,无法主动释放)
Generally the only time you should use semaphore isolation for HystrixCommands is when the call is so high volume (hundreds per second, per instance) that the overhead of separate threads is too high; this typically only applies to non-network calls.
通常,只有在调用量如此之大(每个实例每秒数百个)以至于各个线程的开销过高时,才需要对 HystrixCommands 使用信号隔离。 这通常仅适用于非网络呼叫。(来自官网)
线程池隔离:
它在单独的线程上执行,并发请求受线程池中线程数的限制
通过每次都开启一个单独线程运行。它的隔离是通过线程池,即每个隔离粒度都是个线程池,互相不干扰
。线程池隔离方式,等于多了一层的保护措施,可以通过hytrix直接设置超时,超时后直接返回。
隔离策略修改为信号量
修改为信号量方式,只需要一步操作即可:
- 修改
"execution.isolation.strategy"
属性值为SEMAPHORE
; - 还可以修改另一个关于信号量的属性
fallback.isolation.semaphore.maxConcurrentRequests
,属性默认值为 10,可以根据情况自行修改。
//信号量隔离
@HystrixCommand(fallbackMethod = "降级方法名xxx",commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy",value = "SEMAPHORE"), //开启信号量隔离策略
@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10")//设置信号量隔离允许的最大并发数,默认为10
})
public String xxx(@PathVariable("id") Integer id){
// 方法体
}
缺点:
信号量隔离策略,只有上述两个参数配置,并没有超时时间等属性的配置,操作过于局限。
线程池隔离策略配置,就比它灵活了。支持更多的属性配置。这些属性都有默认值,可以不手动配置。
//线程池隔离()
@HystrixCommand(fallbackMethod = "降级方法名xxx",commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"), //隔离策略:THREAD(默认,可不设置)
@HystrixProperty(name = "execution.isolation.thread.timeoutinMilliseconds", value = "10"), //配置命令执行的超时时间
@HystrixProperty(name = "execution.timeout.enabled", value = "true"), //是否启用超时时间
@HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "true") //执行超时的时候是否中断
})
public String xxx(@PathVariable("id") Integer id){
// 方法体
}
Hystrix 属性默认值介绍,参考官网:https://github.com/Netflix/Hystrix/wiki/Configuration
Hystrix 配置介绍,参考博客:Hystrix 全部配置一览
本文部分内容转载自其它博客
附链接尊重原博主劳动成果。原文链接:https://my.oschina.net/u/867417/blog/2120713
博主写作不易,加个关注呗
求关注、求点赞,加个关注不迷路 ヾ(◍°∇°◍)ノ゙
我不能保证所写的内容都正确,但是可以保证不复制、不粘贴。保证每一句话、每一行代码都是亲手敲过的,错误也请指出,望轻喷 Thanks♪(・ω・)ノ
上一篇: InnoDB 事务与锁的前世今生
下一篇: Java输入字母来判断星期几的实现代码