借鉴地址: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()使用方法:
- 调用observe()会返回一个Observable对象
- 调用这个Observable对象的subscribe()方法完成事件注册,从而获取结果
toObservable()
事件注册后执行run()/construct(),支持接收多个值对象,取决于发射源。调用toObservable()会返回一个cold Observable,也就是说,调用toObservable()不会立即触发执行run()/construct(),必须有订阅者订阅Observable时才会执行。
如果继承的是HystrixCommand,hystrix会从线程池中取一个线程以非阻塞方式执行run(),调用线程不必等待run();如果继承的是HystrixObservableCommand,将以调用线程堵塞执行construct(),调用线程需等待construct()执行完才能继续往下走。
toObservable()使用方法:
- 调用observe()会返回一个Observable对象
- 调用这个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)); }