zoukankan      html  css  js  c++  java
  • hystrix隔离策略(4)

    hystrix提供了两种隔离策略:线程池隔离和信号量隔离。hystrix默认采用线程池隔离。

    1.线程池隔离

    不同服务通过使用不同线程池,彼此间将不受影响,达到隔离效果。
    例如:
    我们可以通过andThreadPoolKey配置使用命名为ThreadPoolTest的线程池,实现与其他命名的线程池天然隔离,如果不配置andThreadPoolKey则使用withGroupKey配置来命名线程池
    public HystrixThreadPoolFallback(String name) {
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ThreadPoolTestGroup"))  
                    .andCommandKey(HystrixCommandKey.Factory.asKey("testCommandKey"))
                    .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("ThreadPoolTest"))   //设置线程池的名字,进行服务隔离
                    .andCommandPropertiesDefaults(
                        HystrixCommandProperties.Setter()
                            .withExecutionTimeoutInMilliseconds(5000)
                    )
                    .andThreadPoolPropertiesDefaults(
                        HystrixThreadPoolProperties.Setter()
                            .withCoreSize(3)    // 配置线程池里的线程数
                    )
            );
            this.name = name;
        }
    

    2.信号量隔离

    线程隔离会带来线程开销,有些场景(比如无网络请求场景)可能会因为用开销换隔离得不偿失,为此hystrix提供了信号量隔离,当服务的并发数大于信号量阈值时将进入fallback。
    通过withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)配置为信号量隔离,通过withExecutionIsolationSemaphoreMaxConcurrentRequests配置执行并发数不能大于3,由于信号量隔离下无论调用哪种命令执行方法,hystrix都不会创建新线程执行run()/construct(),所以调用程序需要自己创建多个线程来模拟并发调用execute(),最后看到一旦并发线程>3,后续请求都进入fallback
     
    /**
     * 测试信号量隔离
     * 默认执行run()用的是主线程,为了模拟并行执行command,这里我们自己创建多个线程来执行command
     * 设置ExecutionIsolationSemaphoreMaxConcurrentRequests为3,意味着信号量最多允许执行run的并发数为3,超过则触发降级,即不执行run而执行getFallback
     * 设置FallbackIsolationSemaphoreMaxConcurrentRequests为1,意味着信号量最多允许执行fallback的并发数为1,超过则抛异常fallback execution rejected
     */
    public class HystrixSemaphoreIsolation extends HystrixCommand<String> {
    
        private final String name;
    
        public HystrixSemaphoreIsolation(String name) {
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SemaphoreTestGroup"))  
                    .andCommandKey(HystrixCommandKey.Factory.asKey("SemaphoreTestKey"))
                    .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("SemaphoreTestThreadPoolKey"))
                    .andCommandPropertiesDefaults(    // 配置信号量隔离
                            HystrixCommandProperties.Setter()
                            .withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)    // 信号量隔离
                            .withExecutionIsolationSemaphoreMaxConcurrentRequests(3)
                            .withFallbackIsolationSemaphoreMaxConcurrentRequests(1)
                    )
                 // 设置了信号量隔离后,线程池配置将变无效
    //                .andThreadPoolPropertiesDefaults(    
    //                        HystrixThreadPoolProperties.Setter()
    //                        .withCoreSize(13)    // 配置线程池里的线程数
    //                )
            );
            this.name = name;
        }
    
        @Override
        protected String run() throws Exception {
            Thread.sleep(100);
            return "run(): name="+name+",线程名是" + Thread.currentThread().getName();
        }
    
        @Override
        protected String getFallback() {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "getFallback(): name="+name+",线程名是" + Thread.currentThread().getName();
        }
    }
    
    @Test
    public void testSynchronous() throws IOException {
         
        try {
            Thread.sleep(2000);
            for(int i = 0; i < 5; i++) {
                final int j = i;
                // 自主创建线程来执行command,创造并发场景
                Thread thread = new Thread(new Runnable() {
                    public void run() {
                        // 这里执行两类command:HystrixSemaphoreIsolation设置了信号量隔离、HelloWorldHystrixCommand未设置信号量
                        //System.out.println("-----------" + new HelloWorldHystrixCommand("HLX" + j).execute());
                        // 被信号量拒绝的线程从这里抛出异常
                        System.out.println("===========" + new HystrixSemaphoreIsolation("HLX" + j).execute());   
                        // 被信号量拒绝的线程不能执行到这里
                        System.out.println("-----------" + new HelloWorldHystrixCommand("HLX" + j).execute());   
                    } 
                }); 
                thread.start();
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
        System.in.read();
    }
    
  • 相关阅读:
    [机器学习]决策树
    [机器学习]Bagging and Boosting
    [机器学习]SVM原理
    [算法]排序算法综述
    天目山大峡谷和西天目山游记【转】
    西天目山出游攻略
    京东物流深度研究报告:京东物流VS亚马逊物流VS顺丰
    「数据标签体系」中台价值链路中“核心的核心”
    网络空间安全概论第一、四章笔记
    21牛客多校第一场
  • 原文地址:https://www.cnblogs.com/cowboys/p/7661969.html
Copyright © 2011-2022 走看看