信号量隔离和线程池隔离的区别以下:html
https://my.oschina.net/u/867417/blog/2120713 java
默认设置:git
因此得注意zuul服务自己的线程池大小,后端服务的线程池大小,以及隔离信号量或线程池的线程池大小,防止1个线程被占用光github
具体设置hytrix参数的setter以下:后端
须要经过zuulProperties从新设置的属性以下:异步
而原生的hytrix.command.default.execution.isolation.strategy和maxConcurrentRequests的配置将失效,会被这3个覆盖socket
当使用线程池隔离时,由于多了一层线程池,并且是用的RXJava实现,故能够直接支持hytrix的超时调用ui
若是使用的是信号量隔离,那么hytrix的超时将会失效,可是ribbon或者socket自己的超时机制依然是有效果的,并且超时后会释放掉信号spa
先看看hytrix信号量的实现:.net
信号量的设置在AbstractCommand里:
用了个ConcurrentHashMap<String, TryableSemaphore> 去保存个计数器的设置,key对应的是commandKey, TryableSemaphore(TryableSemaphoreActual)对应计数器实现,用java的AtomicInter实现,tryAcquire()时,进行原子加incrementAndGet,若是大于设置的maxConcurrentRequests,则进行阻塞
返回fallBack;
执行完后,释放也很简单。原子减去,decrementAndGet。这样看来,信号量就是一个计数器。
那么为何说和超时有关呢,由于超时时,即便访问线程还在阻塞,也会把当前信号量释放。(怎么作的,由于hytrix超时(此时访问线程并未超时)的后续处理部分是由RxJava控制,不是依靠访问线程的超时)
这句会形成,若是你配置了超时1s,如:
hystrix.command.default.execution.timeout.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000
那么你的信号量生效将是1s内,也就是说,过了1s,无论你socket是否超时,hytrix都会释放掉信号量
这一点在上篇有说到,
调用的是hytrix command的excute方法,hytrix的官网原文说明以下:
execute()
— blocks, then returns the single response received from the dependency (or throws an exception in case of an error)execute是一个阻塞方法,也就是说,若是不合理的设置线程池的大小,和超时时间,仍是有可能把zuul的线程消耗完。从而失去对服务的保护做用
总结:
zuul的复杂度很大程度由于集成了hytrix, ribbon,致使设置超时,线程,隔离都有必定的复杂度,自己文档确没那么清楚。
不少地方仍是须要debug分析源码才能避免踩坑。
公众号:
何锦彬 2018.09.25