Hystrix的资源隔离策略

Scroll Down

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