目录
2.1 创建HystrixCommand 或者HystrixObservableCommand
2.6. 执行 HystrixObservableCommand.construct() 或者 HystrixCommand.run()
5. Spring Cloud 下 Hystrix使用要注意的问题
0. Hystrix是什么?
Hystrix的本意是指 豪猪 的动物,它身上长满了很长的较硬的空心尖刺,当受到攻击时,通过后退的方式使其尖刺刺入敌方的身体。作为这种特征的引申,Netflix公司在分布式微服务架构的践行下,将其保护服务的稳定性而设计的客户端熔断和断路器的解决方案,称之为Hystrix。
Hystrix
的设计目的是将应用中的远程系统访问
、服务调用
、第三方依赖包
的调用入口,通过资源控制的方式隔离开,避免了在分布式系统中失败的级联塌方式传递,提升系统的弹性和健壮性。
Hystrix的现状–官方社区已死
Hystrix 当前已经进入为维护阶段,Netflix 认为Hystrix的定位和使命在功能上,当前已经完全满足了既有的内部系统,所以后期不再有新的开发和新的特性出现。团队由于精力的原因,在Github上,不再review issue,不再接受Merge request,也不再发布新的版本,版本定格在1.5.8。
问题:官方社区已死,还有必要学习吗?
Hystrix虽然官方社区不再维护,但是其客户端熔断保护,断路器设计理念,有非常高的学习价值,为我们在服务保护的设计上,提供了非常好的设计思路;除了官方不再维护之外,hystrix目前对于一般的分布式服务调度,甚至本地服务保护上,完全可以胜任,在短期内可以正常使用。
文章末尾会介绍两种替换方案,供参考
1. Hystrix模型基础
- 设计模式:命令模式(Command Pattern)
命令模式 将客户端对服务直接调用,封装成一个待执行的请求,客户端和请求被封装为一个对象,对于服务方而言,每个不同的请求就是不同的参数,从而让我们可用不同的请求对客户进行参数化;命令模式的最大特征就是把客户端和服务端直接关系,通过命令对象进行解耦,在执行上,可以对请求排队或者记录请求日志,以及支持可撤销的操作。
【本文的主旨不是介绍命令模式,读者请参考其他博文进行了解】。
- 线程池和信号量隔离
计算机系统中,线程作为系统运行的基本单位,可以通过划分指定的线程池资源的使用目的,对系统资源进行分离,具备资源限定的能力,进而保护系统;另外在Java中,
Semaphore
的信号量机制,也能提供资源竞争的隔离作用。
2. Hystrix工作原理
如下图所示,Hystrix的工作流程上大概会有如下9
个步骤,下文将详细介绍每个流程:
2.1 创建HystrixCommand
或者HystrixObservableCommand
在使用Hystrix的过程中,会对依赖服务的调用请求封装成命令对象,Hystrix 对 命令对象抽象了两个抽象类:HystrixCommand
和HystrixObservableCommand
。HystrixCommand
表示的命令对象会返回一个唯一值:
public class QueryOrderCommand extends HystrixCommand<Order> {
private String orderId;
public QueryOrderCommand(String orderId){
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("hystrix-order-group"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("hystrix-thread-order"))
.andCommandKey(HystrixCommandKey.Factory.asKey("hystrix-pay-order"))
.andCommandPropertiesDefaults(HystrixCommandProperties.defaultSetter())
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.defaultSetter()
.withCoreSize(10)
.withQueueSizeRejectionThreshold(15)
)
);
this.orderId = orderId;
}
@Override
protected Order run() throws Exception {
System.out.println("fetching order info via service call");
return new Order();
}
}
class Order{
private String orderId;
private String productId;
private String status;
}
HystrixObservableCommand
表示的命令对象 会返回多个返回值:
2.2. 执行命令
Hystrix中共有4种方式执行命令,如下所示:
执行方式 | 说明 | 可用对象 |
execute() | 阻塞式同步执行,返回依赖服务的单一返回结果(或者抛出异常) | HystrixCommand |
queue() | 基于Future的异步方式执行,返回依赖服务的单一返回结果(或者抛出异常) | HystrixCommand |
observe() | 基于Rxjava的Observable方式,返回通过Observable表示的依赖服务返回结果,代调用代码先执行(Hot Obserable) | HystrixObservableCommand |
toObvsevable | 基于Rxjava的Observable方式,返回通过Observable表示的依赖服务返回结果,执行代码等到真正订阅的时候才会执行(cold observable) | HystrixObservableCommand |
这四种命令中,exeucte()
、queue()
、observe()
的表示也是通过toObservable()
实现的,其转换关系如下图所示:
K value = command.execute();
// 等价语句:
K value = command.execute().queue().get();
Future<K> fValue = command.queue();
//等价语句:
Future<K> fValue