-
Hystrix 为何而生
在了解 Hystrix 的思想之前最好先了解它是一项什么技术,为什么目的而产生的,能帮助更好的理解它的隔离思想。 我认为 Hystrix 主要是一项为了提高系统的容错性和高可用性而产生的技术。隔离技术也是为这个大目标而服务的。Hystrix 本质上来说是一种保护性技术,它对整个系统进行保护。
-
分布式系统间服务互相依赖存在的问题
没有 Hystrix 时存在的问题在于 ,当其中依赖的某个服务故障后 Container 线程将有可能长时间的阻塞等待故障服务的响应。当成千上万的并发发生的时候由于其中依赖的某一个服务的故障导致服务器资源被大量的占用无法释放,长时间的挂起等待,服务器的线程会被迅速占用完。如果其他服务再依赖了这个已经被故障服务影响到的服务,那么这个故障就是传播到另一个服务内。同样的服务器资源也会被大量的请求迅速耗尽,最终导致服务宕机,这就是故障引发的雪崩效应,由于一个服务的故障没有被及时感知到并处理导致了这个故障的级联传播,最终整个系统都被影响到。
总结一下就是:由于少数服务的故障的传播导致了服务器资源被迅速的消耗掉,最终使得整个系统瘫痪。
-
Hystrix 希望解决的问题
- 控制服务间依赖调用时候产生的故障和经延时响应。
- 防止级联故障的传播。
- 快速失败和快速恢复。
- 失败回退和降级。
- 近实时监控,警报和操作控制。
-
Hystrix 断路器设计思想
断路器是一种保护措施,比如当同时使用多种大功率电器的时候,电表箱就会跳闸,因为担心会过载所以在达到某一个阙值时就会跳闸,跳闸后就会完全切断电路,对整体电路起到保护的作用。断路器的思想也就是这样。 在 Hystrix 中调用某个依赖多次失败或者超时后,断路器就会处于打开的状态,当断路器打开后再调用该依赖 Hystrix 就不允许再去进行调用了。
-
Hystrix 隔离设计思想
Hystrix 中隔离的主要目的其实是对 Container 资源进行保护。限制依赖调用的并发数。Hystrix 中提供了 2 中隔离策略,Thread 、Semaphores。这两种策略的区别就在于, Thread 是在一个指定的线程中去进行依赖的调用。Semaphores 是在 Container 线程中进行依赖的调用。
-
Thread 隔离
Thread 隔离时,每一个依赖调用都有自己的线程池来负责处理,依赖调用都运行在自己线程池中的线程上,当同一个依赖调用使用的线程池中的 Queue size 达到设置的阙值时就会拒绝进行依赖的调用。虽然此时 Container 线程 依然处于阻塞等待中,但是却可以迅速的继续执行不会等待过长的时间。这也是快速失败思想的一种体现。(一定要注意的是Thread 隔离并没有使 Container 线程释放掉,而依然是处于阻塞等待的状态。)
Thread 隔离的缺点是:要为每个依赖调用开启多个线程,增加了资源的占用,线程上下文切换的开销。
-
Semaphores 隔离
Semaphores 隔离就是利用了 java.util.concurrent.Semaphore 的功能,从信号量获取到许可才允许执行,否则不允许执行,执行完成后要释放之前获取到的许可。同样的每一个服务依赖都有一个自己的信号量,当该信号量的许可被获取完之后,再有线程要进行依赖调用,发现已经没有可用的信号量,这时候就会被拒绝调用。信号量隔离始终都是运行在 Container 线程内的。它的优势就在于造成的开销更低。 -
Hystrix 快速失败思想
快速失败也就是不对结果做正确的预期,如果说等待的时间过长最终得到一个是一个正确的结果。但是考虑到等待的成本可能最终也会变得得不偿失。举个例子:比如我们平时打电话,当呼叫对方号码一段时间内对方没有接听电话,系统就会进行语言提示说对方正在忙或者其他较为友好的提示信息,而不是一直等待直到对方接听电话。因为对于电信运营商来说这种持续等待的成本过高,同时也占用了呼叫方的资源不能释放。这就是快速失败思想的一种体现。在 Hystrix 中通过断路器,依赖调用隔离,Fallback 来实现快速失败。 快速失败的好处就在于可以使得资源被迅速的释放掉,不会长时间无效的占用资源。而 Fallback 会提供一个更友好的结果,类似于电话未接通时的语言提示。
关于 Hystrix 的其他技术点还在学习当中,学习完成后会再次进行总结补充。