天天看点

Hystrix的资源隔离

所谓资源隔离,要解决的最最核心的问题,就是将多个依赖服务的调用分别隔离到各自的资源池内。

资源隔离的作用就是,当前服务所依赖的任何一个服务出现故障,都不会拖垮当前服务。

Hystrix的资源隔离方式有线程池隔离和信号量隔离。

信号量隔离

信号量隔离虽然叫隔离,但它是hystrix的限流功能,信号量相当于一个计数器,当其计数达到设定的阈值,直接做异常处理。而且hystrix信号量隔离限制的是tomcat等Web容器线程数,一段时间仅仅能支持这么多,多余的请求再来请求线程资源,就被拒绝了,也相当于隔离了部分容器的线程资源。

线程池隔离

信号量隔离只是起了个限制作用,它的保护能力有限:如果下游服务有问题,长时间不返回结果。本身信号量隔离对这个单个请求是起不到任何作用的。它只能限制这样的请求太多了就拒绝,不让整个服务挂。

为了解决这个问题,hystrix又产生了线程池隔离。这种隔离方式是通过引入额外线程的方式,其好处是任何一个依赖服务都可以被隔离在自己的线程池内,即使自己的线程池资源填满了,也不会影响任何其他的服务调用。并对原来的web容器线程做管理控制:如果一个线程超时未返回,则熔断。既然引入额外的线程就涉及线程池管理、线程的上下文切换这些额外的开销。所以相比信号量隔离,线程池隔离成本更高。

总结

线程池隔离技术,是用 Hystrix 自己的线程去执行调用;而信号量隔离技术,是直接让 tomcat 线程去调用依赖服务。信号量隔离,只是一道关卡,信号量有多少,就允许多少个 tomcat 线程通过它,然后去执行。

两者的比较如下表所示:

类型 优点 不足 适用场景
线程池 支持排队和超时、支持异步调用 线程调用和切换产生额外开销 不受信客户(比如第三方服务稳定性是无法推测的)、当前服务依赖下游服务
信号量 轻量且无额外开销 不支持任务排队和超时,不支持异步 受信客户、高频高速调用服务(网关、cache)、当前服务不依赖服务

我现在知道信号量隔离是不支持超时的,但是在信号量隔离的模式下,Hystrix又是如何支持超时的呢?其实,信号量隔离采用的是Web容器的线程池,而线程池隔离采用的是自己独立的线程池。