Hystrix的资源隔离策略
Hystrix的资源隔离策略有两种,分别为:线程池和信号量。
线程池
当用户线程请求服务时,会将用户线程交给内部线程来进行执行。当线程池里的线程执行完任务之后,会将调用的结果返回给用户线程,这样从而实现了线程池隔离。当有大量的并发时候,服务内部的线程池的数量也就决定了整个服务的并发度。例如线程池的大小为10,当同时有15个请求,那么只会允许10个任务在执行,其他的任务会被放在线程池队列中,或者直接走降级fallback。如果这时候系统挂掉了就不会造成大量的线程被某一个系统拖死,对整个系统并不会造成太大的影响。
信号量
信号量的资源隔离只是起到一个开关的作用。例如信号量的大小为10,那么同时只允许有10个线程来访问服务,其他的请求都会被拒绝,从而达到限流保护作用。
两者区别
比较 | 线程池隔离 | 信号量隔离 |
---|---|---|
线程 | 与调用线程非相同线程 | 与调用线程相同(jetty线程) |
开销 | 排队、调度、上下文开销等 | 无线程切换,开销低 |
异步 | 支持 | 不支持 |
并发支持 | 支持(最大线程池大小) | 支持(最大信号量上限) |
隔离策略小总结
- 当请求的服务网络开销比较大的时候,或者是请求比较耗时的时候,我们最好是使用线程隔离策略,这样的话,可以保证大量的容器线程可用,不会由于服务原因,一直处于阻塞或等待状态,快速失败返回。
- 当请求缓存这些服务的时候,可以使用信号量隔离策略,因为这类服务的返回通常会非常的快,不会占用容器线程太长时间,而且也减少了线程切换的一些开销,提高了缓存服务的效率。
线程池隔离代码
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolProperties;
/**
* @author 王守钰
* @program quan
* @date 2020年05月16日 18:32
* @description: 线程池隔离
*/
public class HystrixStrategyThreadCommand extends HystrixCommand<String> {
protected HystrixStrategyThreadCommand() {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("HelloWorldGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.defaultSetter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.defaultSetter().withCoreSize(10)));
}
@Override
protected String run() throws Exception {
return "success";
}
@Override
protected String getFallback() {
return "fail";
}
}
测试代码
@Test
public void testThread(){
CountDownLatch countDownLatch = new CountDownLatch(15);
for (int i = 0; i < 15; i++){
HystrixStrategyThreadCommand command = new HystrixStrategyThreadCommand();
new Thread(()->{
String result = command.execute();
log.info("{}, execute result:{}", Thread.currentThread().getName(), result);
countDownLatch.countDown();
}).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true){}
}
执行结果
18:50:30.584 [Thread-3] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-3, execute result:fail
18:50:30.584 [Thread-13] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-13, execute result:fail
18:50:30.584 [Thread-4] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-4, execute result:fail
18:50:30.584 [Thread-10] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-10, execute result:fail
18:50:30.585 [Thread-2] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-2, execute result:fail
18:50:30.593 [Thread-7] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-7, execute result:success
18:50:30.593 [Thread-12] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-12, execute result:success
18:50:30.593 [Thread-1] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-1, execute result:success
18:50:30.593 [Thread-14] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-14, execute result:success
18:50:30.593 [Thread-8] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-8, execute result:success
18:50:30.593 [Thread-9] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-9, execute result:success
18:50:30.593 [Thread-6] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-6, execute result:success
18:50:30.593 [Thread-5] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-5, execute result:success
18:50:30.593 [Thread-0] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-0, execute result:success
18:50:30.593 [Thread-11] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-11, execute result:success
上面测试代码中设置了隔离方式为线程池,并且核心线程数是10,HystrixThreadPoolProperties.defaultSetter().withCoreSize(10)
,那么所以只有10个线程执行时可以成功的,有5个线程走了fallback进行了降级处理。下面调整核心线程数重新测试。
protected HystrixStrategyThreadCommand() {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("HelloWorldGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.defaultSetter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.defaultSetter().withCoreSize(15)));
}
执行结果
18:54:07.280 [Thread-3] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-3, execute result:success
18:54:07.281 [Thread-9] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-9, execute result:success
18:54:07.281 [Thread-5] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-5, execute result:success
18:54:07.282 [Thread-2] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-2, execute result:success
18:54:07.282 [Thread-10] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-10, execute result:success
18:54:07.280 [Thread-1] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-1, execute result:success
18:54:07.283 [Thread-4] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-4, execute result:success
18:54:07.282 [Thread-11] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-11, execute result:success
18:54:07.283 [Thread-8] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-8, execute result:success
18:54:07.281 [Thread-14] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-14, execute result:success
18:54:07.284 [Thread-7] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-7, execute result:success
18:54:07.285 [Thread-6] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-6, execute result:success
18:54:07.285 [Thread-13] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-13, execute result:success
18:54:07.287 [Thread-12] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-12, execute result:success
18:54:07.289 [Thread-0] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-0, execute result:success
信号量隔离代码
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
/**
* @author 王守钰
* @program quan
* @date 2020年05月16日 18:32
* @description: 信号量隔离
*/
public class HystrixStrategySemaphoreCommand extends HystrixCommand<String> {
protected HystrixStrategySemaphoreCommand() {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("HelloWorldGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.defaultSetter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
.withExecutionIsolationSemaphoreMaxConcurrentRequests(10)));
}
@Override
protected String run() throws Exception {
return "success";
}
@Override
protected String getFallback() {
return "fail";
}
}
测试代码
@Test
public void testSemaphore(){
CountDownLatch countDownLatch = new CountDownLatch(15);
for (int i = 0; i < 15; i++){
HystrixStrategySemaphoreCommand command = new HystrixStrategySemaphoreCommand();
new Thread(()->{
String result = command.execute();
log.info("{}, execute result:{}", Thread.currentThread().getName(), result);
countDownLatch.countDown();
}).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
执行结果
19:11:34.433 [Thread-2] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-2, execute result:success
19:11:34.433 [Thread-0] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-0, execute result:fail
19:11:34.434 [Thread-1] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-1, execute result:fail
19:11:34.434 [Thread-9] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-9, execute result:success
19:11:34.434 [Thread-10] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-10, execute result:fail
19:11:34.433 [Thread-12] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-12, execute result:success
19:11:34.434 [Thread-6] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-6, execute result:fail
19:11:34.434 [Thread-4] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-4, execute result:fail
19:11:34.434 [Thread-14] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-14, execute result:success
19:11:34.434 [Thread-13] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-13, execute result:success
19:11:34.434 [Thread-7] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-7, execute result:success
19:11:34.434 [Thread-11] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-11, execute result:success
19:11:34.434 [Thread-8] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-8, execute result:success
19:11:34.434 [Thread-5] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-5, execute result:success
19:11:34.434 [Thread-3] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-3, execute result:success
上面测试代码中我们可以看到执行15个线程时,只有10个线程执行成功,因为我们设置了信号量最大的执行数量为10,HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE).withExecutionIsolationSemaphoreMaxConcurrentRequests(10)
,接下来我们改变信号量大小为15,查看是否全部执行成功。
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("HelloWorldGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.defaultSetter()
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
.withExecutionIsolationSemaphoreMaxConcurrentRequests(15)));
执行结果
19:15:47.797 [Thread-12] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-12, execute result:success
19:15:47.797 [Thread-13] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-13, execute result:success
19:15:47.797 [Thread-6] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-6, execute result:success
19:15:47.797 [Thread-8] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-8, execute result:success
19:15:47.797 [Thread-4] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-4, execute result:success
19:15:47.798 [Thread-5] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-5, execute result:success
19:15:47.798 [Thread-11] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-11, execute result:success
19:15:47.798 [Thread-3] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-3, execute result:success
19:15:47.798 [Thread-2] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-2, execute result:success
19:15:47.798 [Thread-0] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-0, execute result:success
19:15:47.797 [Thread-14] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-14, execute result:success
19:15:47.797 [Thread-9] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-9, execute result:success
19:15:47.798 [Thread-7] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-7, execute result:success
19:15:47.799 [Thread-10] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-10, execute result:success
19:15:47.799 [Thread-1] INFO com.wangshouyu.hystrix.HystrixStrategyTest - Thread-1, execute result:success