execution.isolation.strategy
指定了HystrixCommand.run()的资源隔离策略:THREAD or SEMAPHORE,一种基于线程池,一种基于信号量。
// to use thread isolationHystrixCommandProperties.Setter().withExecutionIsolationStrategy(ExecutionIsolationStrategy.THREAD)// to use semaphore isolationHystrixCommandProperties.Setter().withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)
线程池机制,每个command运行在一个线程中,限流是通过线程池的大小来控制的;信号量机制,command是运行在调用线程中,通过信号量额容量来进行限流。
默认策略是线程池,线程池最大的好处是对于网络访问请求,如果有超时,可以避免调用线程阻塞。
信号量机制主要针对超大并发的场景,每个服务每秒都有几百QPS,如果用线程池,一般不够用,撑不住那么高的并发,那么就需要使用信号量来进行限流保护。
command key & command group
我们使用线程池隔离,怎么对依赖服务、依赖服务接口、线程池三者进行划分呢?
每一个command,都可以设置一个自己的名称command key,同时可以设置一个自己的组command group。
private static final Setter CACHED_SETTER = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")).andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld"));public CommandHelloWorld(String name) {super(CACHED_SETTER);this.name = name;}
默认情况下,是通过command group来定义一个线程池的,而且还会通过command group来聚合一些监控和报警信息。同一个command group中的请求,会进入同一个线程池中。
thread pool
ThreadPoolKey代表了一个HystrixThreadPool,用来进行统一监控、统计、缓存。默认的ThreadPoolKey就是command group的名称,每个command都会跟它的ThreadPoolKey对应的ThreadPool绑定在一起。
如果不想直接用 command group,也可以手动设置 ThreadPool 的名称。
private static final Setter CACHED_SETTER = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")).andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld")).andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("HelloWorldPool"));public CommandHelloWorld(String name) {super(CACHED_SETTER);this.name = name;}
command key & command group & command thread pool
command key,代表一类的command,一般来说,代表了底层的依赖服务的一个接口。
command group,代表了某一个底层的依赖服务,一个依赖服务可能会暴露出多个接口,每个接口就是一个command key。command group在逻辑上去组织起来一堆command key的调用、统计信息、成功次数、timeout次数、失败次数等,可以看到某一个服务整体的一些访问情况。一般来说,推荐根据一个服务区划分出一个线程池,command key默认都是属于同一个线程池。
但是,如果command group对应一个服务,而这个服务暴露出来的接口访问量差异很大,你可能希望在这个服务command group内部,包含的对应多个服务的command key,做一些细粒度的资源隔离,对同一服务的不同接口,使用不同的线程池。
command key -> command groupcommand key -> 自己的 thread pool key
逻辑上,多个command key属于一个command group,在做统计的时候,会放在一起。每个command key有自己的线程池,去做资源隔离和限流。
coreSize
设置线程池的大小,默认是10。一般来说,10个线程大小足够了。
HystrixThreadPoolProperties.Setter().withCoreSize(int value);
queueSizeRejectionThreshold
如果核心线程都在工作,没有空闲的线程接收新的请求,此时再有请求过来,会先进入队列积压。如果队列满了,再有新的请求过来,则直接reject,拒绝请求,执行fallback降级逻辑。
HystrixThreadPoolProperties.Setter().withQueueSizeRejectionThreshold(int value);
execution.isolation.semaphore.maxConcurrentRequests
设置使用 SEMAPHORE 隔离策略的时候允许访问的最大并发量,超过这个最大并发量,请求直接被 reject。
这个并发量的设置,跟线程池大小设置类似,但是信号量的性能要好很多。
默认是10,尽量设置小一些,设置太大,可能导致tomcat本身线程资源被占满。
HystrixCommandProperties.Setter().withExecutionIsolationSemaphoreMaxConcurrentRequests(int value);
