【发布时间】:2015-05-17 09:59:53
【问题描述】:
我曾尝试使用 Spring 框架在 Java 中实现断路器模式 here,但未成功。
如何通过 Java 和 Spring 实现断路器模式?
【问题讨论】:
-
请缩短正文。展示您对工作和初步尝试的承诺。最后问清楚的问题。使用适当的标签。
标签: java spring design-patterns
我曾尝试使用 Spring 框架在 Java 中实现断路器模式 here,但未成功。
如何通过 Java 和 Spring 实现断路器模式?
【问题讨论】:
标签: java spring design-patterns
如需简单直接的circuit breaker implementation,请查看Failsafe。例如:
CircuitBreaker breaker = new CircuitBreaker()
.withFailureThreshold(5)
.withSuccessThreshold(3)
.withDelay(1, TimeUnit.MINUTES);
Failsafe.with(breaker).run(() -> connect());
没有变得更简单。
【讨论】:
Apache commons 有几种轻量级断路器的一些实现,这里是a link to the docs
该项目提供EventCountCircuitBreaker 和ThresholdCircuitBreaker 类,以及一个抽象AbstractCircuitBreaker,因此您可以实现自己的。
代码是开源的并且是hosted at github,所以任何尝试实现该模式的人都应该至少看看。
【讨论】:
Spring cloud 提供了与Hystrix 的一些有趣的集成。你可能应该看看它......
【讨论】:
您可以在Martin Fowler's blog 获得有关此模式的大量有用信息。它包含 ruby 实现以及其他语言实现的参考。
请查看JRugged library。 它包含 Spring 中的 Circuit Breaker 实现以及其他设计模式。
【讨论】:
您实际上不需要使用 Spring Cloud 或 Spring Boot 来使用 Hystrix。
使用 hystrix-javanica 可以很容易地使用 Hystrix 和普通的旧 Spring。
这里是一个回退方法的例子(getMessageTimeout 和 getMessageException 这两个方法都默认失败):
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class CircuitBreakingWithHystrix {
@Bean
public HystrixCommandAspect hystrixAspect() {
return new HystrixCommandAspect();
}
public static void main(String[] args) throws Throwable {
ApplicationContext ctx
= new AnnotationConfigApplicationContext(CircuitBreakingWithHystrix.class);
ExampleService ex = ctx.getBean(ExampleService.class);
for (int i = 0; i < 1000; i++) {
System.out.println(ex.getMessageException());
System.out.println(ex.getMessageTimeout());
}
}
@Service
class ExampleService {
/*
* The default Hystrix timeout is 1 second. So the default
* version of this method will always fail.
* Adding the @HystrixProperty will cause
* the method to succeed.
*/
@HystrixCommand(
commandProperties = {
//@HystrixProperty(name = EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS,
// value = "5000")
},
fallbackMethod = "messageFallback"
)
public String getMessageTimeout() {
try {
//Pause for 4 seconds
Thread.sleep(4000);
} catch (InterruptedException ex) {
// Do something clever with this
}
return "result";
}
@HystrixCommand(
fallbackMethod = "messageFallback")
public String getMessageException() {
throw new RuntimeException("Bad things happened");
}
private String messageFallback(Throwable hre) {
return "fallback";
}
}
您还可以检查发送到回退方法的 throwable 以确定方法调用失败的原因。
【讨论】:
你可以看看JCircuitBreaker。那里的实现实现了类似断路器的方法。
请注意,这不是模式的 1:1 实现,因为它没有定义像“半开”这样的固定状态。相反,它根据当前应用程序状态(使用所谓的“中断策略”)做出决定(是否应该打开或关闭断路器)。尽管如此,应该可以定义这样一个评估故障阈值的“中断策略”——因此也应该可以使用 JCircuitBreaker 实现原始模式。
【讨论】: