gpt4 book ai didi

java - Spring Boot Resilience4J注解不开路

转载 作者:行者123 更新时间:2023-11-30 05:26:51 26 4
gpt4 key购买 nike

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

    @CircuitBreaker(name = "backendA")
@Component
public class ResilientClient {

private HttpClient httpClient;

private static final Logger log = LoggerFactory.getLogger(ResilientClient.class);

public ResilientClient() {

httpClient = HttpClient.newBuilder().build();
}


@Bulkhead(name = "backendA")
public String processPostRequest(String body, String[] headers, String url) {

HttpResponse<String> response = null;

HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.POST(HttpRequest.BodyPublishers.ofString(body))
.headers(headers)
.build();

try {
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException e) {
throw new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, "This is a remote exception");
} catch (InterruptedException e) {
e.printStackTrace();
log.error("Interrupted Exception: " + e.getLocalizedMessage(), e);

}
return response != null ? response.body() : null;
};

// None of these functions ever get invoked

private String fallback(Throwable e){
log.info("generic throwable caught");
return "generic result";
}

private String fallback(String param1, String[] headers, String url, Throwable e) {
log.info("Fallback method invoked for Throwable: " + param1);
return null;
}

private String fallback(String param1, String[] headers, String url, ConnectException e) {
log.info("Fallback method invoked for ConnectException: " + param1);
return 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

尝试测试它的代码

SpringBootApplication
public class CircuitsApplication {

private static final Logger logger = LoggerFactory.getLogger(CircuitsApplication.class);

static ResilientClient resilientClient = new ResilientClient();

public static void main(String[] args) {
//SpringApplication.run(CircuitsApplication.class, args);
for (int i = 0; i < 100; i++){
try {
String body = "body content";
String[] headers = new String[]{"header", "value"};
String url = "http://a.bad.url";
String result = resilientClient.processPostRequest(body, headers, url);
logger.info(result);
} catch (Exception ex){
logger.info("Error caught in main loop");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

}

我尝试将 Circuitbreaker 注释添加到方法本身。我尝试过创建一个供应商并装饰它。我尝试过添加隔板、移除隔板。我尝试添加具有不同签名的其他后备方法。我尝试过使用和不使用 @Component

我最终在日志中得到的就是这 100 次:

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

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

最佳答案

我认为这行不通。首先,您将 ResilientClient 实例化为 new ResilientClient()。您必须使用创建的 Bean,而不是自己实例化它。 @CircuitBreaker 注解使用 spring-aop。因此,您必须将您的类作为 SpringBootApplicaiton 运行。

其次,您仅将 HttpServerErrorExceptionIOException 记录为失败。因此,断路器将所有其他异常(除了上面提到的异常及其子异常)视为成功。

关于java - Spring Boot Resilience4J注解不开路,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58383132/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com