Java 弹簧护套弹性4J注释未断开电路
我已经查看了网站上关于Resilience4J的问题,但没有找到他们的答案。我正试图在我的Spring Boot 2.x项目中实现Resilience4J中的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
@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显式忽略。我知道这一点。我写的。:)如果你不知道