信號量隔離和線程池隔離的區別以下: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