对于单次请求而言,如果[单次请求平均时间/时间窗口]越小,对于单次请求的性能形象越小。如果依赖服务的请求命令本身是一个高延迟的命令,那么可以使用请求合并器,因为延迟时间窗的时间消耗显得微不足道了。
b) 并发量
时间窗口内并发量越大,合并求情的性能提升越明显。如果一个时间窗内只有少数几个请求,那么就不适合使用请求合并器。相反,如果一个时间窗内具有很高的并发量,那么使用请求合并器可以有效减少网络连接数量并极大提升系统吞吐量,此时延迟时间窗所增加的消耗就可以忽略不计了。
6 Hystrix工作流程
下图来自Hystrix官网,其描述了Hystrix的工作流程。
转换成流程图,如下所示:
接下来详细介绍一下这次流程图,以及其中的9步操作。
二 Hystrix工作流程详解
1 创建Command对象
1) 说明
HystrixCommand:用在依赖的服务返回单个操作结果的时候。HystrixObservableCommand:用在依赖的服务返回多个操作结果的时候。通过以下方式创建Command对象。
HystrixCommand command =newHystrixCommand(arg1, arg2);HystrixObservableCommand command =newHystrixObservableCommand(arg1, arg2);
如果通过注解的方式使用HystrixCommand,那么在请求被拦截时,将会在HystrixCommandAspect中创建Command对象。
2) 代码
HystrixCommandAspect #methodsAnnotatedWithHystrixCommand方法
HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ?
metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();
Object result;
try {
result = CommandExecutor.execute(invokable, executionType, metaHolder);
} catch (HystrixBadRequestException e) {
throw e.getCause();
}
HystrixCommandFactory#create方法
public HystrixInvokable create(MetaHolder metaHolder) {HystrixInvokable executable;
if (metaHolder.isCollapserAnnotationPresent()) {
executable = new CommandCollapser(metaHolder);
} else if (metaHolder.isObservable()) {
executable = new GenericObservableCommand (HystrixCommandBuilderFactory. getInstance().create(metaHolder));
} else {
executable = new GenericCommand(HystrixCommandBuilderFactory. getInstance().create(metaHolder));
}
return executable;
}
2 命令执行
1) 代码
通过以下代码我们可以看到Command对象根据方法返回结果类型,决定如何执行命令。
public static Object execute(HystrixInvokable invokable, ExecutionType executionType, MetaHolder metaHolder) throws RuntimeException {Validate.notNull(invokable);
Validate.notNull(metaHolder);
switch (executionType) {
case SYNCHRONOUS: {
return castToExecutable(invokable, executionType).execute();
}
case ASYNCHRONOUS: {
HystrixExecutable executable = castToExecutable(invokable, executionType);
if (metaHolder.hasFallbackMethodCommand()
&& ExecutionType.ASYNCHRONOUS == metaHolder.getFallbackExecutionType()) {
return new FutureDecorator(executable.queue());
}
return executable.queue();
}
case OBSERVABLE: {
HystrixObservable observable = castToObservable(invokable);
return ObservableExecutionMode.EAGER == metaHolder.getObservableExecutionMode() ? observable.observe() : observable.toObservable();
}
default:
throw new RuntimeException("unsupported execution type: " + executionType);
}
}
其中ExecutionType是根据方法的返回结果的类型决定的,代码如下:
CollapserMetaHolderFactory#create方法
ExecutionType.getExecutionType(batchCommandMethod .getReturnType())ExecutionType#getExecutionType方法
public static ExecutionType getExecutionType(Class<?> type) {if (Future.class.isAssignableFrom(type)) {
return ExecutionType.ASYNCHRONOUS;
} else if (Observable.class.isAssignableFrom(type)) {
return ExecutionType.OBSERVABLE;
} else {
return ExecutionType.SYNCHRONOUS;
}
}
HystrixCommand#execute方法
这是Command的同步执行方法。和下面异步方法对比可知仅仅是多了一个Future.get()调用。
public R execute() {try {
return queue().get();
} catch (Exception e) {
throw decomposeException(e);
}
}