Hystrix隔离

什么是Hystrix

Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程池隔离、信号量隔离、熔断、降级回退。在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,比如网络连接变慢,资源突然繁忙,暂时不可用,服务脱机等。我们要构建稳定、可靠的分布式系统,就必须要有这样一套容错方法。 本文将逐一分析线程池隔离、信号量隔离、熔断、降级回退这四种技术的原理与实践。

线程隔离

为什么要做线程隔离

比如我们现在有3个业务调用分别是查询订单、查询商品、查询用户,且这三个业务请求都是依赖第三方服务-订单服务、商品服务、用户服务。三个服务均是通过RPC调用。当查询订单服务,假如线程阻塞了,这个时候后续有大量的查询订单请求过来,那么容器中的线程数量则会持续增加直致CPU资源耗尽到100%,整个服务对外不可用,集群环境下就是雪崩。如下图

线程隔离-线程池

Hystrix是如何通过线程池实现线程隔离的

Hystrix通过命令模式,将每个类型的业务请求封装成对应的命令请求,比如查询订单->订单Command,查询商品->商品Command,查询用户->用户Command。每个类型的Command对应一个线程池。创建好的线程池是被放入到ConcurrentHashMap中,比如查询订单:

1
2
3
final static ConcurrentHashMap<String, HystrixThreadPool> threadPools = new ConcurrentHashMap<String, HystrixThreadPool>();

threadPools.put(“hystrix-order”, new HystrixThreadPoolDefault(threadPoolKey, propertiesBuilder));

当第二次查询订单请求过来的时候,则可以直接从Map中获取该线程池。具体流程如下图:

线程隔离-线程池小结

执行依赖代码的线程与请求线程(比如Tomcat线程)分离,请求线程可以自由控制离开的时间,这也是我们通常说的异步编程,Hystrix是结合RxJava来实现的异步编程。通过设置线程池大小来控制并发访问量,当线程饱和的时候可以拒绝服务,防止依赖问题扩散。

线程池隔离的优点

  1. 应用程序会被完全保护起来,即使依赖的一个服务的线程池满了,也不会影响到应用程序的其他部分。
  2. 我们给应用程序引入一个新的风险较低的客户端lib的时候,如果发生问题,也是在本lib中,并不会影响到其他内容,因此我们可以大胆的引入新lib库。
  3. 当依赖的一个失败的服务恢复正常时,应用程序会立即恢复正常的性能。
  4. 如果我们的应用程序一些参数配置错误了,线程池的运行状况将会很快显示出来,比如延迟、超时、拒绝等。同时可以通过动态属性实时执行来处理纠正错误的参数配置。
  5. 如果服务的性能有变化,从而需要调整,比如增加或者减少超时时间,更改重试次数,就可以通过线程池指标动态属性修改,而且不会影响到其他调用请求。
  6. 除了隔离优势外,hystrix拥有专门的线程池可提供内置的并发功能,使得可以在同步调用之上构建异步的外观模式,这样就可以很方便的做异步编程(Hystrix引入了Rxjava异步框架)。

线程池隔离的缺点

  1. 线程池的主要缺点是它增加了CPU,因为每个命令的执行涉及到排队(默认使用SynchronousQueue避免排队),调度和上下文切换。
  2. 对使用ThreadLocal等依赖线程状态的代码增加复杂性,需要手动传递和清理线程状态(Netflix公司内部认为线程隔离开销足够小,不会造成重大的成本或性能的影响)。

尽管线程池提供了线程隔离,我们的客户端底层代码也必须要有超时设置,不能无限制的阻塞以致线程池一直饱和。

线程隔离-信号量

线程隔离-信号量小结

信号量隔离的方式是限制了总的并发数,每一次请求过来,请求线程和调用依赖服务的线程是同一个线程,那么如果不涉及远程RPC调用(没有网络开销)则使用信号量来隔离,更为轻量,开销更小。

信号量隔离的优点

  1. 不新起线程执行命令,减少上下文切换。

信号量隔离的缺点

  1. 无法配置断路,每次都一定会去尝试获取信号量。

线程池和信号量的区别

  1. 线程隔离是和主线程无关的其他线程来运行的;而信号量隔离是和主线程在同一个线程上做的操作。
  2. 信号量隔离也可以用于限制并发访问,防止阻塞扩散,与线程隔离的最大不同在于执行依赖代码的线程依然是请求线程。
  3. 线程池隔离适用于第三方应用或者接口、并发量大的隔离;信号量隔离适用于内部应用或者中间件;并发需求不是很大的场景。
坚持原创技术分享,您的支持将鼓励我继续创作!