Netflix Hystrix是SOA/微服务架构中提供服务隔离、熔断、降级机制的工具/框架。Netflix Hystrix是断路器的一种实现,用于高微服务架构的可用性,是防止服务出现雪崩的利器。
在分布式架构中,一个应用依赖多个服务是非常常见的,如果其中一个依赖由于延迟过高发生阻塞,调用该依赖服务的线程就会阻塞,如果相关业务的QPS较高,就可能产生大量阻塞,从而导致该应用/服务由于服务器资源被耗尽而拖垮。
另外,故障也会在应用之间传递,如果故障服务的上游依赖较多,可能会引起服务的雪崩效应。就跟数据瘫痪,会引起依赖该数据库的应用瘫痪是一样的道理。
当一个应用依赖多个外部服务,一切都正常的情况下,如下图:
如果其中一个依赖发生延迟,当前请求就会被阻塞
出现这种情况后,如果没有应对措施,后续的请求也会被持续阻塞
每个请求都占用了系统的CPU、内存、网络等资源,如果该应用的QPS较高,那么该应用所以的服务资源会被快速消耗完毕,直至应用死掉。如果这个出问题的依赖(Dependency I),不止这一个应用,亦或是受影响的应用上层也有更多的依赖,那就会带来我们前面所提到的服务雪崩效应。
所以,为了应对以上问题,就需要有支持服务隔离、熔断等操作的工具
所以,当引入了Hystrix之后,当出现某个依赖高延迟的时候:
这些计数器产生的统计数据使得熔断器在特定的时刻,能短路某个依赖服务的后续请求,直到恢复期结束,若恢复期结束根据统计数据熔断器判定线路仍然未恢复健康,熔断器会再次关闭线路。
Hystrix采用舱壁隔离模式隔离相互之间的依赖关系,并限制对其中任何一个的并发访问。
线程&线程池
客户端(通常指Web应用)通过网络请求依赖时,Hystrix会将请求外部依赖的线程与会将App容器(Tomcat/Jetty/…)线程隔离开,以免请求依赖出现延迟时影响请求线程。
Hystrix会为每个依赖维护一个线程池,当线程满载,不会进行线程排队,会Return fallback或者抛出异常
可能会有人有疑问,为什么不依赖于HTTP Client去做容错保护(快速失败、熔断等),而是在访问依赖之外通过线程&线程池隔离的方式做这个断路器(Hystrix)。
主要是以下几个方面:
所以,Hystrix这样设计的好处是:
这样做的成本是,多了一些线程上的资源消耗(排队,调度和上下文切换),不过从官方给到的数据上可能,这个消耗完全可以接受。目前Netflix每天有100亿+的Hystrix命令执行,平均每个应用实例都有40+个线程池。每个线程池有5-20个线程
依然运行良好(不过这里 ken.io 不得不吐槽下,官方没有透露单个实例硬件配置)
官方给了一组测试数据,在单个应用实例60QPS,且每秒钟有350个Hystix子线程(350次Hystrix Command执行)的情况下。Hystrix的线程成本通常为0-3ms,如果CPU使用率超过90%,这个线程成本为有所上升约为9ms。相对于网络请求的时间消耗,这个成本完全可以接受。