Getting Started
Getting started with resilience4j-spring-boot2
Setup
Add the Spring Boot 2 Starter of Resilience4j to your compile dependency.
The module expects that org.springframework.boot:spring-boot-starter-actuator
and org.springframework.boot:spring-boot-starter-aop
are already provided at runtime.
repositories {
jCenter()
}
dependencies {
compile "io.github.resilience4j:resilience4j-spring-boot2:${resilience4jVersion}"
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-aop')
}
Demo
Setup and usage in Spring Boot 2 is demonstrated into a demo.
Configuration
You can configure your CircuitBreaker, Retry, RateLimiter and Bulkead instances in Spring Boot’s application.yml
config file.
For example
resilience4j.circuitbreaker:
backends:
backendA:
registerHealthIndicator: true
ringBufferSizeInClosedState: 100
backendB:
registerHealthIndicator: true
ringBufferSizeInClosedState: 10
ringBufferSizeInHalfOpenState: 3
waitInterval: 50000
failureRateThreshold: 50
eventConsumerBufferSize: 10
recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate
resilience4j.retry:
backends:
backendA:
maxRetryAttempts: 3
waitDuration: 100
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2
retryExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
ignoreExceptions:
- io.github.robwin.exception.BusinessException
backendB:
maxRetryAttempts: 3
waitDuration: 100
retryExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
ignoreExceptions:
- io.github.robwin.exception.BusinessException
resilience4j.bulkhead:
backends:
backendA:
maxConcurrentCall: 10
backendB:
maxWaitTime: 10
maxConcurrentCall: 20
resilience4j.ratelimiter:
limiters:
backendA:
limitForPeriod: 10
limitRefreshPeriodInMillis: 1000
timeoutInMillis: 0
registerHealthIndicator: true
eventConsumerBufferSize: 100
backendB:
limitForPeriod: 6
limitRefreshPeriodInMillis: 500
timeoutInMillis: 3000
You can also override the default configuration, define shared configurations and overwrite them in Spring Boot’s application.yml
config file.
For example:
resilience4j.circuitbreaker:
configs:
default:
ringBufferSizeInClosedState: 100
ringBufferSizeInHalfOpenState: 10
waitInterval: 10000
failureRateThreshold: 60
eventConsumerBufferSize: 10
registerHealthIndicator: true
someShared:
ringBufferSizeInClosedState: 50
ringBufferSizeInHalfOpenState: 10
backends:
backendA:
baseConfig: default
waitInterval: 5000
backendB:
baseConfig: someShared
Annotations
The Spring Boot2 starter provides annotations and AOP Aspects which are auto-configured.
RateLimiter, Retry, CircuitBreaker and Bulkhead annotations support synchronous return types and asynchronous types like CompletableFuture and reactive types like Spring Reactor's Flux and Mono.
@CircuitBreaker(name = BACKEND, fallbackMethod = "fallback")
@RateLimiter(name = BACKEND)
@Bulkhead(name = BACKEND)
@Retry(name = BACKEND, fallbackMethod = "fallback")
public Mono<String> method(String param1) {
return Mono.error(new NumberFormatException());
}
private Mono<String> fallback(String param1, IllegalArgumentException e) {
return Mono.just("test");
}
private Mono<String> fallback(String param1, RuntimeException e) {
return Mono.just("test");
}
It's important to remember that a fallback method should be placed in the same class and must have the same method signature (and an optional exception parameter).
If there are multiple fallbackMethod methods, the method that has the most closest match will be invoked, for example:
If you try to recover from NumberFormatException
, the method with signature String fallback(String parameter, IllegalArgumentException exception)}
will be invoked.
Aspect order
You can adjust the order of AOP Aspects with RateLimiterProperties.rateLimiterAspectOrder
, CircuitBreakerProperties.circuitBreakerAspectOrder
, RetryProperties.retryAspectOrder
and BulkheadProperties.bulkheadAspectOrder
.
Metrics endpoint
CircuitBreaker, Retry, RateLimiter and Bulkhead Metrics are automatically published on the Metrics endpoint. To retrieve the names of the available metrics, make a GET request to /actuator/metrics
. Please see Actuator Metrics documentation for more details.
{
"names": [
"resilience4j.circuitbreaker.calls",
"resilience4j.circuitbreaker.max.buffered.calls",
"resilience4j.circuitbreaker.buffered.calls",
"resilience4j.circuitbreaker.state",
"resilience4j.circuitbreaker.failure.rate"
]
}
To retrieve a metric, make a GET request to /actuator/metrics/{metric.name}
.
For example: /actuator/metrics/resilience4j.circuitbreaker.calls
{
"name": "resilience4j.circuitbreaker.calls",
"measurements": [
{
"statistic": "VALUE",
"value": 3
}
],
"availableTags": [
{
"tag": "kind",
"values": [
"not_permitted",
"successful",
"failed"
]
},
{
"tag": "name",
"values": [
"backendB",
"backendA"
]
}
]
}
When you want to publish CircuitBreaker endpoints on the Prometheus endpoint, you have to add the dependency io.micrometer:micrometer-registry-prometheus
.
To retrieve metrics, make a GET request to /actuator/prometheus
. For more details please see Micrometer Getting Started
Health endpoint
Spring Boot Actuator health information can be used to check the status of your running application. It is often used by monitoring software to alert someone if a production system has serious issues. The Spring Boot starter publishes the status via custom CircuitBreakerHealthIndicators.
A closed CircuitBreaker state is mapped to UP, an open state to DOWN and a half-open state to UNKNOWN.
We actually think that RateLimiter and Bulkheads should not be part of the aggregrated health status as your application isn't down when a Bulkhead is full or a rate limit is exceeded.
For example:
{
"status": "DOWN",
"backendACircuitBreaker": {
"status": "DOWN",
"failureRate": "60.0%",
"failureRateThreshold": "50.0%",
"maxBufferedCalls": 5,
"bufferedCalls": 5,
"failedCalls": 3,
"notPermittedCalls": 0
},
"backendBCircuitBreaker": {
"status": "UP",
"failureRate": "0.0%",
"failureRateThreshold": "50.0%",
"maxBufferedCalls": 10,
"bufferedCalls": 10,
"failedCalls": 0,
"notPermittedCalls": 0
},
"backendARateLimiter": {
"status": "UP",
"availablePermissions": 10,
"numberOfWaitingThreads": 0
}
}
Events endpoint
The emitted CircuitBreaker, Retry, RateLimiter and Bulkhead events are stored in a separate circular event consumer buffers. The size of a event consumer buffer can be configured in the application.yml file (eventConsumerBufferSize).
The endpoint /actuator/circuitbreakers
lists the names of all CircuitBreaker instances. The endpoint is also available for Retry, RateLimiter and Bulkhead.
For example:
{
"circuitBreakers": [
"backendA",
"backendB"
]
}
The endpoint /management/circuitbreaker-events
lists by default the latest 100 emitted events of all CircuitBreaker instances. The endpoint is also available for Retry, RateLimiter and Bulkhead.
{
"circuitBreakerEvents":[
{
"circuitBreakerName": "backendA",
"type": "ERROR",
"creationTime": "2017-01-10T15:39:17.117+01:00[Europe/Berlin]",
"errorMessage": "org.springframework.web.client.HttpServerErrorException: 500 This is a remote exception",
"durationInMs": 0
},
{
"circuitBreakerName": "backendA",
"type": "SUCCESS",
"creationTime": "2017-01-10T15:39:20.518+01:00[Europe/Berlin]",
"durationInMs": 0
},
{
"circuitBreakerName": "backendB",
"type": "ERROR",
"creationTime": "2017-01-10T15:41:31.159+01:00[Europe/Berlin]",
"errorMessage": "org.springframework.web.client.HttpServerErrorException: 500 This is a remote exception",
"durationInMs": 0
},
{
"circuitBreakerName": "backendB",
"type": "SUCCESS",
"creationTime": "2017-01-10T15:41:33.526+01:00[Europe/Berlin]",
"durationInMs": 0
}
]
}
Updated over 5 years ago