Java 弹簧护套弹性4J注释未断开电路

Java 弹簧护套弹性4J注释未断开电路,java,spring-boot,circuit-breaker,resilience4j,Java,Spring Boot,Circuit Breaker,Resilience4j,我已经查看了网站上关于Resilience4J的问题,但没有找到他们的答案。我正试图在我的Spring Boot 2.x项目中实现Resilience4J中的@CircuitBreaker注释。断路器是围绕一个非常简单的功能实现的。然而,当我提供一个错误的URL时,无论我发送了多少次请求,电路都不会打开。我甚至将所有内容提取到一个独立的应用程序中,运行100次,然后观察到它不断失败。知道我做错了什么吗 断路器(name=“backendA”) @组成部分 公共类弹性客户端{ 私有HttpClie

我已经查看了网站上关于Resilience4J的问题,但没有找到他们的答案。我正试图在我的Spring Boot 2.x项目中实现Resilience4J中的
@CircuitBreaker
注释。断路器是围绕一个非常简单的功能实现的。然而,当我提供一个错误的URL时,无论我发送了多少次请求,电路都不会打开。我甚至将所有内容提取到一个独立的应用程序中,运行100次,然后观察到它不断失败。知道我做错了什么吗

断路器(name=“backendA”) @组成部分 公共类弹性客户端{ 私有HttpClient HttpClient; 私有静态最终记录器log=LoggerFactory.getLogger(ResilientClient.class); 公共弹性客户端(){ httpClient=httpClient.newBuilder().build(); } @隔板(name=“backendA”) 公共字符串processPostRequest(字符串正文、字符串[]头、字符串url){ HttpResponse响应=null; HttpRequest请求=HttpRequest.newBuilder() .uri(uri.create(url)) .POST(HttpRequest.bodypublisher.ofString(body)) .标题(标题) .build(); 试一试{ response=httpClient.send(请求,HttpResponse.BodyHandlers.ofString()); }捕获(IOE异常){ 抛出新的HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR,“这是一个远程异常”); }捕捉(中断异常e){ e、 printStackTrace(); 错误(“中断的异常:+e.getLocalizedMessage(),e); } 返回响应!=null?response.body():null; }; //这些函数都不会被调用 私有字符串回退(可丢弃的e){ log.info(“通用一次性捕获”); 返回“一般结果”; } 私有字符串回退(字符串参数1、字符串[]头、字符串url、可丢弃的e){ log.info(“为Throwable调用的回退方法:“+param1”); 返回null; } 私有字符串回退(字符串参数1、字符串[]头、字符串url、连接异常){ info(“为ConnectException调用的回退方法:”+param1); 返回null; } } 配置文件直接取自Github示例

resilience4j.circuitbreaker:
  configs:
    default:
      registerHealthIndicator: false
      slidingWindowSize: 10
      minimumNumberOfCalls: 5
      permittedNumberOfCallsInHalfOpenState: 3
      automaticTransitionFromOpenToHalfOpenEnabled: true
      waitDurationInOpenState: 2s
      failureRateThreshold: 50
      eventConsumerBufferSize: 10
      recordExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException
      ignoreExceptions:
        - io.github.robwin.exception.BusinessException
    shared:
      registerHealthIndicator: true
      slidingWindowSize: 100
      permittedNumberOfCallsInHalfOpenState: 30
      waitDurationInOpenState: 1s
      failureRateThreshold: 50
      eventConsumerBufferSize: 10
      ignoreExceptions:
        - io.github.robwin.exception.BusinessException
  instances:
    backendA:
      baseConfig: default
    backendB:
      registerHealthIndicator: true
      slidingWindowSize: 10
      minimumNumberOfCalls: 10
      permittedNumberOfCallsInHalfOpenState: 3
      waitDurationInOpenState: 1s
      failureRateThreshold: 50
      eventConsumerBufferSize: 10
      recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate
resilience4j.retry:
  configs:
    default:
      maxRetryAttempts: 2
      waitDuration: 100
      retryExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException
      ignoreExceptions:
        - io.github.robwin.exception.BusinessException
  instances:
    backendA:
      maxRetryAttempts: 3
    backendB:
      maxRetryAttempts: 3
resilience4j.bulkhead:
  configs:
    default:
      maxConcurrentCalls: 100
  instances:
    backendA:
      maxConcurrentCalls: 10
    backendB:
      maxWaitDuration: 10ms
      maxConcurrentCalls: 20

resilience4j.thread-pool-bulkhead:
  configs:
    default:
      maxThreadPoolSize: 4
      coreThreadPoolSize: 2
      queueCapacity: 2
  instances:
    backendA:
      baseConfig: default
    backendB:
      maxThreadPoolSize: 1
      coreThreadPoolSize: 1
      queueCapacity: 1

resilience4j.ratelimiter:
  configs:
    default:
      registerHealthIndicator: false
      limitForPeriod: 10
      limitRefreshPeriod: 1s
      timeoutDuration: 0
      eventConsumerBufferSize: 100
  instances:
    backendA:
      baseConfig: default
    backendB:
      limitForPeriod: 6
      limitRefreshPeriod: 500ms
      timeoutDuration: 3s

尝试测试它的代码

springboot应用程序
公共类电路应用{
私有静态最终记录器Logger=LoggerFactory.getLogger(CircuitsApplication.class);
静态ResilientClient ResilientClient=新的ResilientClient();
公共静态void main(字符串[]args){
//run(CircuitsApplication.class,args);
对于(int i=0;i<100;i++){
试一试{
字符串body=“body content”;
字符串[]头=新字符串[]{“头”,“值”};
字符串url=”http://a.bad.url";
字符串结果=resilientClient.processPostRequest(正文、标题、url);
logger.info(结果);
}捕获(例外情况除外){
logger.info(“在主循环中捕获错误”);
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
}
}
我已经尝试将断路器注释添加到方法本身。我试着创建一个供应商并对其进行装饰。我试着增加隔板,拆除隔板。我已尝试添加具有不同签名的其他回退方法。我试过使用和不使用
@组件

我在日志中得到的结果是100次:

14:33:10.348 [main] INFO c.t.circuits.CircuitsApplication - Error caught in main loop

我不确定我错过了什么。任何帮助都将不胜感激。

我认为这行不通。首先,将您的
ResilientClient
实例化为
newresilientclient()
。您必须使用创建的Bean,而不是自己实例化它。
@断路器
注释使用spring aop。所以你必须以SpringbootApplication的身份运行你的类


其次,您只将
HttpServerErrorException
IOException
记录为失败。因此,断路器将所有其他异常(除上述异常及其子项外)视为成功。

要清楚,上述代码是我从Spring Boot应用程序中提取的代码。:)现在,客户端是使用
(@Autowired ResilientClient ResilientClient)从构造函数的服务层实例化的。
在Spring Boot 2中有几个使用Resilience4J的项目没有在文档中介绍,包括需要Spring自动连接bean或设置配置类,文档中的示例Java代码有一个未定义的变量尝试将
Java.lang.Throwable
添加到
resilience4j.circuitbreaker.configs.default。如果要重试所有异常,请记录异常
。您可以将忽略的异常添加到
resilience4j.circuitbreaker.configs.default。ignoreExceptions
默认情况下,所有异常均视为失败。您不必向recordExceptions添加Throwable。您只需将异常添加到ignoreExpections列表中即可。如果不配置
recordExceptions
,则可以。但是,如果您在
recordExceptions
config中列出异常列表,则它们不会<代码>记录异常:记录为故障并因此增加故障率的异常列表。除非通过ignoreExceptions显式忽略,否则任何与列表之一匹配或继承的异常都视为失败。如果您指定一个异常列表,则所有其他异常都视为成功,除非它们被ignoreExceptions显式忽略。我知道这一点。我写的。:)如果你不知道