Hystrix超时时间配置

Hystrix配置整体的超时时间

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000

配置参考github

配置单个超时时间

hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds=1000

1
2
3
4
5
6
7
8
9
10
11
12
其中HystrixCommandKey为@HystrixCommand 进行配置
example
@HystrixCommand(groupKey = "StoreSubmission", commandKey = "StoreSubmission", threadPoolKey = "StoreSubmission")
public String storeSubmission(ReturnType returnType, InputStream is, String id) {
}
@HystrixCommand需要引入依赖
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>${hystrix-version}</version>
</dependency>

配置参考stackoverflow

在fegin中配置超时时间

在fegin中无法使用@HystrixCommand来单独进行配置

1
hystrix.command.MyService#getLastTimeData(Map).execution.isolation.thread.timeoutInMilliseconds这种可以的,通过实践验证了 @甲申验证

配置原理

HystrixInvocationHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
final class HystrixInvocationHandler implements InvocationHandler {
private final Target<?> target;
private final Map<Method, MethodHandler> dispatch;
private final FallbackFactory<?> fallbackFactory; // Nullable
private final Map<Method, Method> fallbackMethodMap;
private final Map<Method, Setter> setterMethodMap;//时间配置
static Map<Method, Setter> toSetters(SetterFactory setterFactory, Target<?> target,
Set<Method> methods) {
Map<Method, Setter> result = new LinkedHashMap<Method, Setter>();
for (Method method : methods) {
method.setAccessible(true);
result.put(method, setterFactory.create(target, method));
}
return result;
}

SetterFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public interface SetterFactory {
/**
* Returns a hystrix setter appropriate for the given target and method
*/
HystrixCommand.Setter create(Target<?> target, Method method);
/**
* Default behavior is to derive the group key from {@link Target#name()} and the command key from
* {@link Feign#configKey(Class, Method)}.
*/
final class Default implements SetterFactory {
@Override
public HystrixCommand.Setter create(Target<?> target, Method method) {
String groupKey = target.name();
String commandKey = Feign.configKey(target.type(), method);
return HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey));
}
}
}

fegin

1
2
3
4
5
6
7
8
9
10
11
12
13
public static String configKey(Class targetType, Method method) {
StringBuilder builder = new StringBuilder();
builder.append(targetType.getSimpleName());
builder.append('#').append(method.getName()).append('(');
for (Type param : method.getGenericParameterTypes()) {
param = Types.resolve(targetType, targetType, param);
builder.append(Types.getRawType(param).getSimpleName()).append(',');
}
if (method.getParameterTypes().length > 0) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.append(')').toString();
}

对应上面的规则就可以解释了

1
2
hystrix.command.MyService#getLastTimeData(Map).execution.isolation.thread.timeoutInMilliseconds
其中MyService#getLastTimeData(Map)为commandKey有configKey进行生成

hystrix生效

1
2
3
4
5
6
HystrixInvocationHandler.invoke->
newHystrixCommand->execute->toObservable->
addTimerListener(executionTimeoutInMilliseconds)->
ScheduledThreadPoolExecutor.scheduleAtFixedRate-call-TimerListener.tick->
timeoutRunnable.run->throw HystrixTimeoutException
简单来说就是创建一个ScheduledThreadPoolExecutor,超时时间后执行抛出异常操作,如果超时时间执行完成会吧这个Reference应用干掉

ps

群里看到的问题,闲顺便翻了下源码。有错误请指出,避免误人子弟

参考