1.资源隔离
hystrix默认的策略就是线程池,execution.isolation.strategy:指定了HystrixCommand.run()的资源隔离策略
- 线程池隔离
线程池其实最大的好处就是对于网络访问请求,如果有超时的话,可以避免调用线程阻塞住 - 信号量隔离
(1) 通常是针对超大并发量的场景下,每个服务实例每秒都几百的QPS,那么此时你用线程池的话,线程一般不会太多,可能撑不住那么高的并发,如果要撑住,可能要耗费大量的线程资源,那么就是用信号量,来进行限流保护
(2) 一般用信号量常见于那种基于纯内存的一些业务逻辑服务,而不涉及到任何网络访问请求
2.服务、接口、线程池如何划分
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GetCityNameGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey("GetCityNameCommand"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("GetCityNamePool"))
-
HystrixCommandKey
command名称,如果未指定,使用的接口名称。一般是某个服务中的一个接口。 -
HystrixCommandGroupKey
(1)command组,一般是某个服务,这个服务可能有多个接口,每个接口一个command key。
(2)在逻辑上去组织起来一堆command key的调用,统计信息,成功次数,timeout超时次数,失败次数,可以看到某一个服务整体的一些访问情况
(3)比如说你以一个服务为粒度,估算出来这个服务每秒的所有接口加起来的整体QPS。在100左右你调用那个服务的当前服务,部署了10个服务实例,每个服务实例上,其实用这个command group对应这个服务,给一个线程池,量大概在10个左右,就可以了,你对整个服务的整体的访问QPS大概在每秒100左右。 -
HystrixThreadPoolKey
线程池名称,如果未指定,使用command组 -
对同一个服务的不同接口,也可以使用不同的线程池
(1)command key -> command group
(2)command key -> 自己的threadpool key
3.hystrix高级控制
3.1 coreSize
设置线程池的大小,默认是10
HystrixThreadPoolProperties.Setter()
.withCoreSize(int value)
一般来说,用这个默认的10个线程大小就够了。
3.2 queueSizeRejectionThreshold
HystrixThreadPoolProperties.Setter()
.withQueueSizeRejectionThreshold(int value)
-
控制queue满后reject的threshold,因为maxQueueSize不允许热修改,因此提供这个参数可以热修改,控制队列的最大大小。
-
HystrixCommand在提交到线程池之前,其实会先进入一个队列中,这个队列满了之后,才会reject。默认值是5。
3.3 execution.isolation.semaphore.maxConcurrentRequests
HystrixCommandProperties.Setter()
.withExecutionIsolationSemaphoreMaxConcurrentRequests(int value)
-
设置使用SEMAPHORE隔离策略的时候,允许访问的最大并发量,超过这个最大并发量,请求直接被reject
-
这个并发量的设置,跟线程池大小的设置,应该是类似的,但是基于信号量的话,性能会好很多,而且hystrix框架本身的开销会小很多
-
默认值是10,设置的小一些,否则因为信号量是基于调用线程去执行command的,而且不能从timeout中抽离,因此一旦设置的太大,而且有延时发生,可能瞬间导致tomcat本身的线程资源本占满