Hytrix看起来很简单,貌似使用默认配置就行,但实际使用起来坑多多,稍不留意,就会入坑。
一 线程池
coresize
比如这个coresize,默认是10,平常看起来是ok的,但一旦面临高并发,就会爆掉
如图所示,用户请求都会被包装成一个hytrix请求,hytrix使用ThreadPoolExecutor来管理线程池,一旦超限,就会爆掉
比如有30个rps,平均每个请求响应时间为0.2s,那么需要的线程数就是30*0.2=6,然后加上一个附加值,比如说4,6+4=10
如果是100rqs,每个响应时间0.2, 100*0.2=20,那就是至少20个线程。当然,此时请求平均响应时间应该会延长,应该根据实际情况计算。
按照文档说设置这个值过大会影响性能,但个人以为设置成100并不会有何问题。
maximumSize
有了coresize当然有maximumsize了,一般coresize = maximumsize,只有当你设置allowMaximumSizeToDivergeFromCoreSize=true时才起作用
maxQueueSize
线程池的队列配置,如果线程超过线程池大小coresize,会进入该队列排队。默认是-1,就是SynchronousQueue,如果设置为正值,会使用LinkedBlockingQueue。该配置不可修改,如果修改,必须要重启应用才会生效。
queueSizeRejectionThreshold
队列的拒绝门槛。即使在队列中排队的线程未达到最大值,只要超过了这个阀值,请求线程都会被丢弃掉,所以maxQueueSize某种意义是没用的
keepAliveTimeMinutes
线程在队列中的存活事件,默认值是1(应该是1s),需要allowMaximumSizeToDivergeFromCoreSize=true
allowMaximumSizeToDivergeFromCoreSize
设置maximumSize和keepAliveTimeMinutes是否起作用,默认是false,就是不起作用
二 滑动窗口与阀值微调
大家都知道断路器会跳闸,但到底是如何跳闸呢?是失败多少次么?那么是不是还需要一个时间值,来判断多长时间失败多少次。有点类似于一个滑动窗口:
- Hystrix遇到服务错误时,会开启一个10s的窗口
- 如果在该窗口内错误调用未达到阀值,那么程序继续
- 如果达到阀值,那么断路器会跳闸
- 跳闸的同时,会启动一个新的活动窗口5s
- 在5s的窗口期间会尝试将一个请求发到对方服务
- 如果失败,继续保持断路状态
- 如果成功,重启10s的滑动窗口
]
@HystrixCommand(
fallbackMethod = "buildFallbackLicenseList",
threadPoolKey = "licenseByOrgThreadPool",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value="30"),
@HystrixProperty(name = "maxQueueSize" value="10"),
},
commandPoolProperties = {
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="10"),
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value="75"),
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="7000"),
@HystrixProperty(name="metrics.rollingStats.timeInMilliseconds", value="15000"),
@HystrixProperty(name="metrics.rollingStats.numBuckets", value="5")
}
)
public String doSth(){....}
各参数说明如下:
circuitBreaker.requestVolumeThreshold
表示在10s中必须发生的连续调用次数阀值。比如这个值是20,那么及时在10s的时间窗口中全部19个请求失败了,也不会触发熔断。
circuitBreaker.errorThresholdPercentage
错误阀值,超过这个阀值会触发熔断,所有的请求都会打到fallback上
circuitBreaker.sleepWindowInMilliseconds
发生熔断后,熔断器会睡眠多长时间后,才会再次尝试访问对方服务
metrics.rollingStats.timeInMilliseconds
窗口大小,默认10s
metrics.rollingStats.numBuckets
桶的个数,必须被timeInMilliseconds整除。比如numBuckets=2,那么 timeInMilliseconds/numBuckets = 5,就是在5秒内Hystrix展开监控