结合函数式接口 Supplier 使用熔断器 Hystrix
前言
如果你只需要使用 Hystrix 的注解形式就够了,那本篇文章对你没什么意义,但如果是采用继承 HystrixCommand 类进行使用,可以结合函数式接口 Supplier 进行更解耦的实现,对业务的侵入小,并且代码的相互依赖低
代码
我们先来看一段代码
private Boolean equal(String s1, String s2) {
return equalStr(s1, s2);
}
private Boolean equalStr(String s1, String s2) {
return s1.equals(s2);
}
只采用继承 HystrixCommand 类进行使用
如果你直接把这段代码采用继承 HystrixCommand 类进行使用,并且用s1作为熔断标识
private Boolean equal(String s1, String s2) {
return new StrCommand(s1, s2).execute();
}
public class StrCommand extends HystrixCommand<Boolean> {
private String s1;
private String s2;
public StrCommand(String s1, String s2) {
// 熔断标识
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(s1))
.andCommandKey(HystrixCommandKey.Factory.asKey(s1))
.andCommandPropertiesDefaults(
// 熔断超时时间
HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(Config.OUT_TIME)
// 单位统计时间
.withMetricsRollingStatisticalWindowInMilliseconds(Config.WINDOW_TIME)
// 统计请求数量阈值
.withCircuitBreakerRequestVolumeThreshold(Config.NUMBER_OF_REQUESTS)
// 错误百分比
.withCircuitBreakerErrorThresholdPercentage(Config.ERROR_PERCENTAGE)
// 休眠时间
.withCircuitBreakerSleepWindowInMilliseconds(Config.SLEEP_TIME)));
this.s1 = s1;
this.s2 = s2;
}
@Override
protected Boolean run() throws Exception {
return s1.equals(s2);
}
@Override
protected Boolean getFallback() {
System.out.println("熔断");
return false;
}
}
有注意到吗,你需要把整个equalStr重构为 HystrixCommand 类,不仅要把整个原来的逻辑挪出来,而且 HystrixCommand 类里的属性也很多,这把业务性代码和功能性代码揉到一起,对于后续的其他实现也有影响,所以,我们不妨结合函数式接口 Supplier 进行更解耦的实现
结合函数式接口 Supplier
private Boolean equal(String s1, String s2) {
Supplier<Boolean> supplier = () -> equalStr(s1, s2);
return new StrCommand(supplier).execute();
}
private Boolean equalStr(String s1, String s2) {
return s1.equals(s2);
}
public class StrCommand extends HystrixCommand<Boolean> {
private Supplier<Boolean> supplier;
public StrCommand(Supplier supplier) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(s1))
.andCommandKey(HystrixCommandKey.Factory.asKey(s1))
.andCommandPropertiesDefaults(
// 熔断超时时间
HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(Config.OUT_TIME)
// 单位统计时间
.withMetricsRollingStatisticalWindowInMilliseconds(Config.WINDOW_TIME)
// 统计请求数量阈值
.withCircuitBreakerRequestVolumeThreshold(Config.NUMBER_OF_REQUESTS)
// 错误百分比
.withCircuitBreakerErrorThresholdPercentage(Config.ERROR_PERCENTAGE)
// 休眠时间
.withCircuitBreakerSleepWindowInMilliseconds(Config.SLEEP_TIME)));
this.supplier = supplier;
}
@Override
protected Boolean run() throws Exception {
return supplier.get();
}
@Override
protected Boolean getFallback() {
System.out.println("熔断");
return false;
}
}
看到了吗,这样业务性代码和功能性代码就完全隔离开来,后续无论是要调整熔断,还是要改进原来的业务代码,双方都没有影响,这就是更优雅的实现
希望有所帮助,完