最近在看springcloud的组件之一的熔断器Hystrix。说起熔断器,第一反应就是回想起小时候经常发生的保险丝烧断的情况。熔断的意思大概与其类似吧。只不过这次保护的不是电力系统而是我们的应用系统而已。
当一个应用系统的规模愈来愈大以后,常常一个简单的请求会依赖多个服务。如果其中某个服务出现了问题,任何进入其中的请求都被阻塞而无法及时作出响应时,与其相关联的多个服务都会被阻塞,从而导致多个服务的不可用,甚至导致整个应用系统的不可用。这在商业运营商是不可接受的。于是为了保证单个或者少数服务的异常不影响到其他服务,不将异常状态扩散到其他系统依赖的服务上,我们需要熔断器。
Hystrix是Netflix公司开源的熔断器组件,也是本文讨论得主角。Hystrix的工作原理如下图:
可大致分为如下几步:
1.将请求装饰成熔断器命令
2.选择合适的方式执行命令
3.查看是否有缓存结果
4.查看是否开启circuit-breaker
5.信号量/队列/线程池是否已满
6.可选方式执行在对应服务执行请求获取结果
7.检查circuit健康状况
8.失败情况返回
9.成功返回正确响应
1.将请求装饰成熔断器命令
Hystrix提供了2种方式来创建熔断器命令。分别为:
HystrixCommand command = new HystrixCommand(arg1, arg2);
HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
2.选择合适的方式执行命令
Hystrix提供了4种方式来执行命令:
K value = command.execute(); Future<K> fValue = command.queue(); Observable<K> ohValue = command.observe(); //hot observable Observable<K> ocValue = command.toObservable(); //cold observable
execute方法为阻塞方法,执行命令后返回结果
queue方法会返回一个Future
observe注册一个Observable
并返回一个源Observable
的复制体
toObservable返回一个Observable
并激活它的响应
3.查看是否有缓存结果
如果有缓存,返回一个包含响应的Observable
4.查看是否开启circuit-breaker
检查是否开启circuit-breaker。如果开启,则所有请求跳到步骤8直接返回failed,否则继续执行下一步步骤5。
5.信号量/队列/线程池是否已满
检查信号量/队列/线程池是否满载。如果满载则跳到步骤8返回failed,否则执行下一步步骤6。
6.可选方式执行在对应服务执行请求获取结果
HystrixObservableCommand.construct()
返回一个Observable
并激活其中的影响或者添加一个onError的提醒
HystrixCommand.run()
直接返回响应或者抛出异常
7.检查circuit健康状况
8.失败情况返回
HystrixCommand.getFallback()
直接返回一个值
HystrixObservableCommand.resumeWithFallback()
返回一个Observable
包含错误状态
9.成功返回正确响应
正确返回影响的情况较多,有待下次分析。
未完待续...