hystrix线程池隔离技术
1. 首先hystrix会把每个业务请求封装成对应的命令模式(Command),每个类型的Command会对于一个线程池,创建好的线程池会被放入ConcurrentHashMap中,这样,当下一次同样类型的请求过来的时候,就会直接从ConcurrentHashMap中取出对于的线程池,具体过程如下图:
2. 然后hystrix会检查对应类型的请求,是否已经在缓冲中,如果存在,则直接接结果返回,如果不存在,则进入熔断器检查阶段;
3. hystrix会检查熔断器(cirruite breaker)是否开启,如果开启,则直接返回fallback,如果此时线程池已满,也会进入fa'l否则就进入线程池,拿到对于的线程执行construct()或者run()方法。hystrix内部会有一个检查机制(metrics report)不断反馈熔断器和线程池的状态。
4 .hystrix会以执行Command的方式来执行服务的调用,执行Command的方式一共四种
-
execute():以同步堵塞方式执行run()。调用execute()后,hystrix先创建一个新线程运行run(),接着调用程序要在execute()调用处一直堵塞着,直到run()运行完成。
-
queue():以异步非堵塞方式执行run()。调用queue()就直接返回一个Future对象,同时hystrix创建一个新线程运行run(),调用程序通过Future.get()拿到run()的返回结果,而Future.get()是堵塞执行的。
-
observe():事件注册前执行run()/construct()。第一步是事件注册前,先调用observe()自动触发执行run()/construct()(如果继承的是HystrixCommand,hystrix将创建新线程非堵塞执行run();如果继承的是HystrixObservableCommand,将以调用程序线程堵塞执行construct()),第二步是从observe()返回后调用程序调用subscribe()完成事件注册,如果run()/construct()执行成功则触发onNext()和onCompleted(),如果执行异常则触发onError()。
-
toObservable():事件注册后执行run()/construct()。第一步是事件注册前,调用toObservable()就直接返回一个Observable<String>对象,第二步调用subscribe()完成事件注册后自动触发执行run()/construct()(如果继承的是HystrixCommand,hystrix将创建新线程非堵塞执行run(),调用程序不必等待run();如果继承的是HystrixObservableCommand,将以调用程序线程堵塞执行construct(),调用程序等待construct()执行完才能继续往下走),如果run()/construct()执行成功则触发onNext()和onCompleted(),如果执行异常则触发onError()
注:
注意:execute()和queue()是在HystrixCommand中,observe()和toObservable()是在HystrixObservableCommand 中。从底层实现来讲,HystrixCommand其实也是利用Observable实现的(看Hystrix源码,可以发现里面大量使用了RxJava),尽管它只返回单个结果。HystrixCommand的queue方法实际上是调用了toObservable().toBlocking().toFuture(),而execute方法实际上是调用了queue().get()。
总图如下: