Hystrix熔断的方法级别(自定义commonKey)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Hystrix熔断的⽅法级别(⾃定义commonKey)
⼀、Hystrix的Feign熔断的粒度
Feign可以直接去集成Hystrix熔断,那么默认的熔断粒度是多⼤呢?或者说,当serviceA调⽤serviceB#method1(param)时,如果出现超时导致熔断后,serviceA还能不能调⽤serviceB#method2(param)呢?
我做了⼀个模拟测试,当serviceA调⽤serviceB#method1(param)时,报错信息如下:
flix.hystrix.exception.HystrixRuntimeException: serviceB#method1(param) short-circuited and no fallback available.
at flix.hystrix.AbstractCommand$22.call(AbstractCommand.java:819)
当serviceA调⽤serviceB#method2(param)时,请求和返回都是正常的。

结论:Hystrix熔断的粒度是⽅法层⾯的。

根据上⾯的报错的AbstractCommand.java:819跟进到源码中:
toEmit = new HystrixRuntimeException(failureType, _cmd.getClass(), getLogMessagePrefix() + " " + message + " and no fallback available.", e, fe);
//serviceB#method1(param)的来源
protected String getLogMessagePrefix() {
return getCommandKey().name();
}
//
public HystrixCommandKey getCommandKey() {
return commandKey;
}
//group默认是服务名称
mandGroup = initGroupKey(group);
//key默认是feignclient的类名#method(参数名称)
mandKey = initCommandKey(key, getClass());
//
private static HystrixCommandKey initCommandKey(final HystrixCommandKey fromConstructor, Class<?> clazz) {
if (fromConstructor == null || ().trim().equals("")) {
final String keyName = getDefaultNameFromClass(clazz);
return HystrixCommandKey.Factory.asKey(keyName);
} else {
return fromConstructor;
}
}
也就是说熔断的粒度是FeignClient类下的⽅法层⾯。

⼆、⾃定义熔断的范围
Feign-灵活的使⽤Hystrix熔断(⾃定义CommandKey)
但是配置时,却不是很灵活,只是⽀持default和类名#⽅法名()的配置。

这就不能对类或者⼀组⽅法进⾏统⼀的配置。

源码改造:
@Configuration
public class MyHystrixFeign {
@Bean
@Scope("prototype")
@ConditionalOnProperty(name = "feign.hystrix.enabled")
public Feign.Builder feignHystrixBuilder() {
return HystrixFeign.builder().setterFactory(new MyDefault());
}
/**
* 修改源码{@link HystrixFeign.Builder#setterFactory}
*/
final class MyDefault implements SetterFactory {
@Override
public HystrixCommand.Setter create(Target<?> target, Method method) {
String groupKey = ();
String commandKey = Feign.configKey(target.type(), method);
//
if ("TestDemoApi1".equals(target.type().getSimpleName())) {
return HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey("TestDemoApi1"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(commandKey));
}
return HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey));
}
}
}
项⽬启动后,会遍历@Feign注解类中的每⼀个⽅法调⽤create⽣成Hystrix的配置key,也可以是线程池的key。

源码位置:feign.hystrix.HystrixInvocationHandler#toSetters如下图所⽰。

/**
* Process all methods in the target so that appropriate setters are created.
* 为每⼀个⽅法增加熔断的配置(可以在代码中配置,也可以在yml中进⾏配置)。

*/
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;
}
yml的配置:
feign:
# Dalston SR1(待定)之后的版本默认关闭hystrix对feign的⽀持,如果想要使⽤fallback功能这⾥必须启⽤。

hystrix:
enabled: true
#
#
#hystrix:
# command:
# default:
# execution:
# isolation:
# thread:
# timeoutInMilliseconds: 100000 # 调⽤者执⾏的超时时间默认是1s
# threadpool:
# default:
# coreSize: 1 #核⼼线程数
# maximumSize: 1 # 最⼤线程数
# maxQueueSize: 0 # 不使⽤队列
#
## Feign仅仅⽀持⽅法级别和default级别
hystrix:
command:
TestDemoApi1: ## ⽀持类级别
execution:
isolation:
thread:
timeoutInMilliseconds: 4000 # 调⽤者执⾏的超时时间默认是1s
注:默认情况下,Feign-Hystrix会使⽤服务名作为CommandGroup,使⽤类名#⽅法名作为CommandKey。

⽽在yml配置:全局配置是default的配置,⽽实例配置为commandKey配置。

更多的配置,可以参考。

相关文档
最新文档