I'm trying to integrate fault tolerance in a microservice by using Resilience4j library.
I have:
build.gradle :
...
buildscript {
ext {
springBootVersion = '2.2.4.RELEASE'
lombokVersion = '1.18.10'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
plugins {
id 'org.springframework.boot' version '2.2.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'com.sample'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "Hoxton.SR8")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.boot:spring-boot-configuration-processor'
compile 'io.github.resilience4j:resilience4j-spring-boot2:1.7.0'
implementation 'io.micrometer:micrometer-registry-prometheus'
}
application.yml file:
resilience4j.circuitbreaker:
configs:
default:
registerHealthIndicator: true
slidingWindowSize: 5
minimumNumberOfCalls: 5
permittedNumberOfCallsInHalfOpenState: 3
automaticTransitionFromOpenToHalfOpenEnabled: true
waitDurationInOpenState: 5s
failureRateThreshold: 50
eventConsumerBufferSize: 10
recordExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.util.concurrent.TimeoutException
- java.io.IOException
ignoreExceptions:
- com.example.githubtest.BusinessException
shared:
slidingWindowSize: 100
permittedNumberOfCallsInHalfOpenState: 30
waitDurationInOpenState: 1s
failureRateThreshold: 50
eventConsumerBufferSize: 10
ignoreExceptions:
- com.example.githubtest.BusinessException
instances:
serviceA:
baseConfig: default
Rest Controller :
...
@RestController
public class MyController {
private final RestTemplate rest;
public MyController() { this.rest = new RestTemplate(); }
@GetMapping(path = "foo")
@CircuitBreaker(name = "serviceA", fallbackMethod = "customFallback")
public String foo() {
throw new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, "This is a remote exception");
}
@GetMapping(path = "bar")
public String bar() {
// Does not get to OPEN state
return invokeService();
}
@CircuitBreaker(name = "serviceA", fallbackMethod = "customFallback")
public String invokeService() {
throw new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, "This is a remote exception");
}
public String customFallback(Exception e) {
if (e instanceof CallNotPermittedException) {
System.out.println("Call no permitted!");
}
System.out.println(e.getMessage());
return "Fallback default return";
}
}
There are 2 endpoints: foo & bar
"foo" mapper wrapped with circuit breaker annotation which eventually opens the circuit after N failures
"bar" mapper invokes another method with some business logic and invokes a method wrapped with circuit breaker annotation. In this case, I'm not able to reach OPEN state to handle these scenarios properly according to business rules. I always get failures.
What should I do or change in order to start reaching OPEN state in the second case to be able to handle call not permitted exceptions properly?
Thank you
Because of the way Spring AOP works, the proxies are skipped if you invoke an annotated method from within the same class. You have to extract invokeService()
into another bean/class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.