hytrix支持线程池隔离和信号量隔离
- 信号量隔离适应非网络请求,因为是同步的请求,无法支持超时,只能依靠协议本身
- 线程池隔离,即,每个实例都增加个线程池进行隔离
先给个总结对比:
隔离方式
是否支持超时
是否支持熔断
隔离原理
是否是异步调用
资源消耗
线程池隔离
支持,可直接返回
支持,当线程池到达maxSize后,再请求会触发fallback接口进行熔断
每个服务单独用线程池
可以是异步,也可以是同步。看调用的方法
大,大量线程的上下文切换,容易造成机器负载高
信号量隔离
不支持,如果阻塞,只能通过调用协议(如:socket超时才能返回)
支持,当信号量达到maxConcurrentRequests后。再请求会触发fallback
通过信号量的计数器
同步调用,不支持异步
小,只是个计数器
看官网的定义引用理解
信号量的隔离:
- it executes on the calling thread and concurrent requests are limited by the semaphore count
- 引自官网
自我理解:
每次调用线程,当前请求通过计数信号量进行限制,当信号大于了最大请求数(maxConcurrentRequests)时,进行限制,调用fallback接口快速返回。
最重要的是,信号量的调用是同步的,也就是说,每次调用都得阻塞调用方的线程,直到结果返回。这样就导致了无法对访问做超时(只能依靠调用协议超时,无法主动释放)
官网对信号量隔离的描述建议
- Generally the only time you should use semaphore isolation for
HystrixCommand
s is when the call is so high volume (hundreds per second, per instance) that the overhead of separate threads is too high; this typically only applies to non-network calls.
理解下两点:
- 隔离的细粒度太高,数百个实例需要隔离,此时用线程池做隔离开销过大
- 通常这种都是非网络调用的情况下
线程池隔离:
- it executes on a separate thread and concurrent requests are limited by the number of threads in the thread-pool
通过每次都开启一个单独线程运行。它的隔离是通过线程池,即每个隔离粒度都是个线程池,互相不干扰
- Commands executed in threads have an extra layer of protection against latencies beyond what network timeouts can offer.
线程池隔离方式,等于多了一层的保护措施,可以通过hytrix直接设置超时,超时后直接返回。
分享个以前的一个误解
以前对zuul网关的一个误解,以为网关用的是线程池隔离是属于异步调用的,以为只要用了线程池隔离,不需要去考虑本身具体的线程池大小了。
具体看源码:
调用的是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的线程消耗完。从而失去对服务的保护作用
公众号:
何锦彬 2018.09.21