hystrix隔离策略
zuul的隔离实现是基于hystrix实现的,hystrix支持线程池隔离和信号量的隔离
# 信号量隔离:
- it executes on the calling thread and concurrent requests are limited by the semaphore count --引自官网
- 单每次调用线程,当前请求通过技术信号量进行限制,当信号量大于了最大请求数(maxConcurrentRequest)时候,触发限制,调用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.
- Generally the only time you should use semaphore isolation for
- 两点:
- 隔离的粒度太细,数百个实例需要隔离,此时用线程池做隔离开销过大
- 通常这种都是非网络调用的情况下
# 线程池隔离
- 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.
线程池隔离方式,等于多了一层保护措施,可以通过hystryx直接设置超时时间,超时后直接返回
对比表格‘:
隔离方式 | 是否支持超时 | 是否支持熔断 | 隔离原理 | 是否异步调用 | 资源消耗 |
---|---|---|---|---|---|
线程池隔离 | 支持,可以直接返回 | 支持,当线程池达到maxsize后,再请求会出发fallback熔断 | 每个服务单独用线程池 | 可以是异步,也可以是同步。看调用的方法 | 消耗大,大量线程的上下文切花,容易造成机器负载过高 |
信号量隔离 | 不支持,如果阻塞,只能通过调用协议比如socket超时返回 | 支持,当信号量达到maxConcurrentRequests后,再请求会触发fallback熔断 | 通过信号量计数器 | 同步调用,不支持异步 | 消耗小,只是一个计数器 |
- zuul网关如果使用线程池隔离是属于异步调用,其实查看源码如下:
调用的是hystrix 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的线程消耗完。从而失去对服务的保护作用