断路器设计模式实现

20

我曾尝试使用Spring框架在Java中实现断路器模式(Circuit Breaker Pattern),但未能成功。这里是相关介绍.

如何在Java和Spring中实现断路器模式?


1
请保持正文简短。展示你对工作的承诺和初步尝试。最后提出明确的问题。使用适当的标签。 - Léo Léopold Hertz 준영
7个回答

20

对于一个简单、直接的断路器实现,请查看我编写的Failsafe。例如:

CircuitBreaker breaker = new CircuitBreaker()
  .withFailureThreshold(5)
  .withSuccessThreshold(3)
  .withDelay(1, TimeUnit.MINUTES);

Failsafe.with(breaker).run(() -> connect());

再简单不过了。


1
你在备用方案中会做什么? - VedantK

13

Apache commons提供了多种轻量级熔断器的实现,其中包括CircuitBreaker文档的链接

该项目提供了EventCountCircuitBreakerThresholdCircuitBreaker类,以及一个抽象类AbstractCircuitBreaker,因此您可以实现自己的熔断器。

代码是开源的,托管在GitHub上,所以任何试图实现此模式的人都应该至少看一眼。


5

你应该看一下Resilience4J,而不是已经被弃用的Hystrix(来源)。 - Paulo Merson

4

关于该模式本身

您可以在Martin Fowler的博客中获取关于此模式的许多有用信息。它包含了Ruby实现以及其他语言实现的参考。

关于Java Spring实现

请查看JRugged库。 它包含了Spring中的断路器实现以及其他设计模式。


你好,是否有使用Java和Spring一起实现电路断路器的任何Web服务的具体实现? - user2585494
感谢您的快速回复,我已经查看了JRugged库,它很不错,但是我觉得它有点庞大。然而,我需要立即处理一个紧急情况,需要使用断路器,并且正在寻找任何简单的Spring解决方案。请给予建议并分享。 - user2585494

2
您可以查看JCircuitBreaker。该实现采用类似断路器的方法。
请注意,这不是模式的1:1实现,因为它没有定义像“半开”这样的固定状态。相反,它基于当前应用程序状态(使用所谓的“断开策略”)做出决策(如果断路器应该打开或关闭)。尽管如此,仍然应该有可能定义这样的“断开策略”,以评估故障阈值 - 因此也应该能够使用JCircuitBreaker实现原始模式。

2

您实际上不需要使用Spring Cloud或Spring Boot就可以使用Hystrix。
使用hystrix-javanica可以使普通的Spring与Hystrix轻松结合。

以下是回退方法的示例(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";
    }

  }

您还可以检查传递给回退方法的可抛对象,以确定方法调用失败的原因。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接