I am using resilience4j for fault tolerance in reative API spring boot application. I can see that all events are treated as success even though Mono is returning errors.
service layer
@Override
@CircuitBreaker(name = "member-service")
public Mono<String> getMemberInfo(String memberId) {
return wsClient.getMemberInfo(memberId);
// This call will return WSException whenever there is 4XX or 5XX error
}
application.yml configuration
resilience4j.circuitbreaker:
backends:
member-service:
ringBufferSizeInClosedState: 1
ringBufferSizeInHalfOpenState: 2
waitInterval: 10000
failureRateThreshold: 75
registerHealthIndicator: true
recordExceptions:
- com.xx.WSException
ignoreExceptions:
- com.xxx.WSClientException
I intentionally changed URI path, so that WebClient always return 404 error, which throws WSException. When I see below endpoint, type is always SUCCESS. Did I miss something?
http://localhost:8088/circuitbreaker-events/member-service
{
"circuitBreakerEvents": [
{
"circuitBreakerName": "member-service",
"type": "SUCCESS",
"creationTime": "2019-02-18T21:56:21.588+05:30[Asia/Calcutta]",
"durationInMs": 6
},
{
"circuitBreakerName": "member-service",
"type": "SUCCESS",
"creationTime": "2019-02-18T21:56:21.588+05:30[Asia/Calcutta]",
"durationInMs": 5
},
{
"circuitBreakerName": "member-service",
"type": "SUCCESS",
"creationTime": "2019-02-18T21:56:21.588+05:30[Asia/Calcutta]",
"durationInMs": 6
}
}
Your method always returns Mono. Even if there is an error. And @CircuitBreaker
annotation reacts on exception (not error Mono
).
So you should apply CircuitBreakerOperator
to your reactive code.
public class MemberService {
private final WsClient wsClient;
private final CircuitBreaker circuitBreaker;
public MemberService(WsClient wsClient,
CircuitBreakerRegistry circuitBreakerRegistry,
CircuitBreakerProperties circuitBreakerProperties) {
this.wsClient = wsClient;
this.circuitBreaker = circuitBreakerRegistry.circuitBreaker(
"member-service",
() -> circuitBreakerProperties
.createCircuitBreakerConfig("member-service"));
}
public Mono<String> getMemberInfo(String memberId) {
return wsClient.getMemberInfo(memberId)
.transform(CircuitBreakerOperator.of(circuitBreaker));
}
}
You need resilience4j-reactor
and resilience4j-spring-boot2
dependencies.