当前位置: 首页 > 知识库问答 >
问题:

弹性4j断路器不工作

林元明
2023-03-14

我正面临使用Spring Cloud Resilience 4j的断路器实现的问题。

在一些教程之后,我尝试在项目中添加必要的依赖项。此外,尝试添加配置,但电路仍然没有打开,并且没有调用回退方法。

对于用例,我正在从我的服务调用外部 API,如果该外部 API 关闭,那么在几次调用后,我需要启用断路器。

请从不同的文件中找到代码片段。

我是断路器模式的新手。我们将非常感谢您的帮助。

pom.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.5.5</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>
    <properties>
    <java.version>11</java.version>
    <spring-cloud.version>2020.0.4</spring-cloud.version>
    </properties>
    <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
<dependencies>
</project>

应用程序属性

resilience4j.circuitbreaker.instances.test-api.register-health-indicator=true
resilience4j.circuitbreaker.instances.test-api.minimum-number-of-calls=4
resilience4j.circuitbreaker.instances.test-api.failure-rate-threshold=50
resilience4j.circuitbreaker.instances.test-api.permitted-number-of-calls-in-half-open-state=3
resilience4j.circuitbreaker.instances.test-api.wait-duration-in-open-state=30s
resilience4j.circuitbreaker.instances.test-api.automatic-transition-from-open-to-half-open-enabled=true
resilience4j.circuitbreaker.instances.test-api.record-exceptions=com.testapi.exception.ServiceUnavailableError

服务等级代码段

@CircuitBreaker(name = "test-api", fallbackMethod = "storeResponseFallback")
    public TestResponse storeResponse(String apiURL, HttpEntity<String> entityrequest) {

        TestResponse testResponse = new TestResponse();
        Optional<ResponseEntity<TestResponse>> response = Optional.empty();
        Future<ResponseEntity<TestResponse>> responseFuture;

        ExecutorService executor = Executors.newFixedThreadPool(10);

        log.debug("Calling Extrenal API, Request Body: {}", entityrequest.toString());

        try {
            //Service call returns a future
            responseFuture = executor.submit(() -> restTemplate.postForEntity(apiURL, entityrequest, TestResponse.class));
            response = Optional.ofNullable(responseFuture.get());
            log.info("Got response from external API");


            if ((response.isPresent()) && (response.get().hasBody())) {
                testResponse = response.get().getBody();
            }

        } catch (Exception exception) {
            log.error("External api call got failed with an error");
            Thread.currentThread().interrupt();            
            throw new ServiceUnavailableError();
        }


        return testResponse;

    }
    
    
    public TestResponse storeResponseFallback(ServiceUnavailableError ex) {
        log.error("Executing Fallback Method For General exceptions");
        throw new ServiceUnavailableError();
    }

ServiceUnavailableError Java文件

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ServiceUnavailableError extends RuntimeException{
    private static final long serialVersionUID = 2382122402994502766L;

    private String message;

}

共有2个答案

闻人业
2023-03-14

我已经准备好了视频,其中我定义了主服务和目标服务,我正在从配置准备豆子并使用 Try.of(),请检查视频是否有帮助。您将看到回退方法工作正常。https://www.youtube.com/watch?v=8yJ0xek6l6Y

易奇希
2023-03-14

回退方法的签名错误。它应该包含实际方法的所有参数(在您的案例中,storeResponseFallback是回退方法,storeResponse是实际方法),以及例外。请确保删除尝试捕获块。您不想自己处理异常,而应该让断路器为您处理。请查看以下代码,该代码来自给定的链接 https://resilience4j.readme.io/docs/getting-started-3

@CircuitBreaker(name = BACKEND, fallbackMethod = "fallback")
public Mono<String> method(String param1) {
    return Mono.error(new NumberFormatException());
}

private Mono<String> fallback(String param1, IllegalArgumentException e) {
    return Mono.just("test");
}

尝试使用以下yaml文件我对现有代码使用了以下配置,我使用了yaml而不是属性文件。这似乎保持在打开状态,只调用回退方法。

resilience4j.circuitbreaker:
  configs:
    default:
      slidingWindowSize: 4
      permittedNumberOfCallsInHalfOpenState: 10
      waitDurationInOpenState: 10000
      failureRateThreshold: 60
      eventConsumerBufferSize: 10
      registerHealthIndicator: true
    someShared:
      slidingWindowSize: 3
      permittedNumberOfCallsInHalfOpenState: 10
  instances:
    test-api:
      baseConfig: default
      waitDurationInOpenState: 500000
    backendB:
      baseConfig: someShared

这是更新的回退方法

public TestResponse storeResponseFallback(String apiURL, String entityrequest, java.lang.Throwable t) {
        log.error("Executing Fallback Method For General exceptions "+t.getMessage());
        return new TestResponse("Frm Fallback");// Making sure to send a blank response
    }
 类似资料:
  • 我使用的是Resilience4J断路器,我需要忽略一些自定义异常,所以我需要更改默认配置。我在使用微服务,所以我有一个连接到数据库的微服务,它有一些基本的请求,比如get by id,我还有一个使用这些请求的边缘服务。例如,我需要,如果id不存在,微服务会抛出一个自定义异常,在这种情况下断路器不会打开。 数据库的微服务: 获取请求 > 服务 public SalesRepDTO getSales

  • 我想用Resilience4j来处理容错,我用的是断路器和定时器限制。 我想分离业务逻辑的容错行为,不要“弄脏”我的业务代码。 2-我如何有这个应用程序的许多实例,断路器为每个实例单独工作?我是对的?

  • 断路器将处于闭合或半断开状态无限时间,直到达到最小的呼叫次数,对吗?有什么办法我可以设置什么时候没有调用在数量的时间,它将转为关闭状态?另外,在半开状态下,是否有可能使最小呼叫数大于允许的呼叫数?谢谢。

  • 我可以看到,我可以使用以下代码以编程方式将状态设置为强制打开:CircuitBreaker强制打开状态 但是有没有一种方法可以设置一个属性,在应用程序启动时立即将状态设置为此,以便可以与测试一起使用呢?

  • 我有一个关于带Resilience4J(不仅仅是Resilience4J)的Spring Cloud断路器的快速问题。 这两个项目都非常棒。然而,目前,我们经常以撤退告终。这意味着,当第三方服务真的很好时,我们最终还是会选择后退。 这可能是我自己的问题,因此,我想问一个特定配置的问题。 我想告诉当前配置做以下操作:断路器。(我将使用好的,坏的,和一半好/一半坏的状态。 > 当状态是一半好/一半坏:

  • 根据入门指南(https://Resilience4j.readme.io/docs/get-started-3)和演示项目(https://github.com/Resilience4j/Resilience4j-spring-boot2-demo),我想自己测试它,创建一个更简单的测试应用程序。 代码如下: