zoukankan      html  css  js  c++  java
  • Histrix原理和实战---资源隔离

    借鉴地址:https://blog.csdn.net/loushuiyifan/article/details/82702522

    1.资源隔离:

    (信号量隔离)

    public class QueryByOrderIdCommandSemaphore extends HystrixCommand<Integer> {
        private final static Logger logger = LoggerFactory.getLogger(QueryByOrderIdCommandSemaphore.class);
        private OrderServiceProvider orderServiceProvider;
     
        public QueryByOrderIdCommandSemaphore(OrderServiceProvider orderServiceProvider) {
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("orderService"))
                    .andCommandKey(HystrixCommandKey.Factory.asKey("queryByOrderId"))
                    .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                            .withCircuitBreakerRequestVolumeThreshold(10)至少有10个请求,熔断器才进行错误率的计算
                            .withCircuitBreakerSleepWindowInMilliseconds(5000)//熔断器中断请求5秒后会进入半打开状态,放部分流量过去重试
                            .withCircuitBreakerErrorThresholdPercentage(50)//错误率达到50开启熔断保护
                            .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
                            .withExecutionIsolationSemaphoreMaxConcurrentRequests(10)));//最大并发请求量
            this.orderServiceProvider = orderServiceProvider;
        }
     
        @Override
        protected Integer run() {
            return orderServiceProvider.queryByOrderId();
        }
     
        @Override
        protected Integer getFallback() {
            return -1;
        }
    }
    

      第二步,调用HystrixCommand的执行方法发起实际请求。

    @Test
    public void testQueryByOrderIdCommand() {
        Integer r = new QueryOrderIdCommand(orderServiceProvider).execute();
        logger.info("result:{}", r);
    }
    

      

    执行命令的几种方法

    Hystrix提供了4种执行命令的方法,execute()和queue() 适用于HystrixCommand对象,而observe()和toObservable()适用于HystrixObservableCommand对象。

    execute()

    以同步堵塞方式执行run(),只支持接收一个值对象。hystrix会从线程池中取一个线程来执行run(),并等待返回值。

    queue()

    以异步非阻塞方式执行run(),只支持接收一个值对象。调用queue()就直接返回一个Future对象。可通过 Future.get()拿到run()的返回结果,但Future.get()是阻塞执行的。若执行成功,Future.get()返回单个返回值。当执行失败时,如果没有重写fallback,Future.get()抛出异常。

    observe()

    事件注册前执行run()/construct(),支持接收多个值对象,取决于发射源。调用observe()会返回一个hot Observable,也就是说,调用observe()自动触发执行run()/construct(),无论是否存在订阅者。

    如果继承的是HystrixCommand,hystrix会从线程池中取一个线程以非阻塞方式执行run();如果继承的是HystrixObservableCommand,将以调用线程阻塞执行construct()。

    observe()使用方法:

    1. 调用observe()会返回一个Observable对象
    2. 调用这个Observable对象的subscribe()方法完成事件注册,从而获取结果

    toObservable()

    事件注册后执行run()/construct(),支持接收多个值对象,取决于发射源。调用toObservable()会返回一个cold Observable,也就是说,调用toObservable()不会立即触发执行run()/construct(),必须有订阅者订阅Observable时才会执行。

    如果继承的是HystrixCommand,hystrix会从线程池中取一个线程以非阻塞方式执行run(),调用线程不必等待run();如果继承的是HystrixObservableCommand,将以调用线程堵塞执行construct(),调用线程需等待construct()执行完才能继续往下走。

    toObservable()使用方法:

    1. 调用observe()会返回一个Observable对象
    2. 调用这个Observable对象的subscribe()方法完成事件注册,从而获取结果

    需注意的是,HystrixCommand也支持toObservable()和observe(),但是即使将HystrixCommand转换成Observable,它也只能发射一个值对象。只有HystrixObservableCommand才支持发射多个值对象。

    几种方法的关系

    • execute()实际是调用了queue().get()
    • queue()实际调用了toObservable().toBlocking().toFuture()
    • observe()实际调用toObservable()获得一个cold Observable,再创建一个ReplaySubject对象订阅Observable,将源Observable转化为hot Observable。因此调用observe()会自动触发执行run()/construct()。

    Hystrix总是以Observable的形式作为响应返回,不同执行命令的方法只是进行了相应的转换。

    线程池隔离

    final static ConcurrentHashMap<String, HystrixThreadPool> threadPools = new ConcurrentHashMap<String, HystrixThreadPool>();
    ...
    if (!threadPools.containsKey(key)) {
        threadPools.put(key, new HystrixThreadPoolDefault(threadPoolKey, propertiesBuilder));
    }
    

      

  • 相关阅读:
    第04组(64) 需求分析报告
    第04组(64) 团队展示
    结对编程作业
    Python单元测试框架 Unittest 的简单使用方法
    第一次个人编程作业
    第09组 Alpha冲刺 总结
    Swagger 工具集
    第09组 Alpha冲刺(6/6)
    第09组 Alpha冲刺(5/6)
    第09组 Alpha冲刺(4/6)
  • 原文地址:https://www.cnblogs.com/MaxElephant/p/14874921.html
Copyright © 2011-2022 走看看