Getting Started
Getting started with resilience4j-ratpack
Setup
Add the Ratpack Starter of Resilience4j to your compile dependency:
repositories {
jCenter()
}
dependencies {
compile "io.github.resilience4j:resilience4j-ratpack:${resilience4jVersion}"
}
Demo
Setup and usage in Ratpack is demonstrated into a demo.
Configuration
You can configure your CircuitBreaker, Retry, RateLimiter , Bulkead and Thread pool bulkhead instances in Ratpack’s application.yml
config file.
For example
resilience4j:
circuitbreaker:
instances:
backendA:
ringBufferSizeInClosedState: 100
backendB:
ringBufferSizeInClosedState: 10
ringBufferSizeInHalfOpenState: 3
waitDurationInOpenState: PT50S
failureRateThreshold: 50
eventConsumerBufferSize: 10
recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate
retry:
instances:
backendA:
maxRetryAttempts: 3
waitDuration: PT10S
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2
retryExceptions:
- java.io.IOException
ignoreExceptions:
- io.github.robwin.exception.BusinessException
backendB:
maxRetryAttempts: 3
waitDuration: PT10S
retryExceptions:
- java.io.IOException
ignoreExceptions:
- io.github.robwin.exception.BusinessException
bulkhead:
instances:
backendA:
maxConcurrentCall: 10
backendB:
maxWaitDuration: PT0.01S
maxConcurrentCall: 20
threadpoolbulkhead:
instances:
backendC:
threadPoolProperties:
maxThreadPoolSize: 1
coreThreadPoolSize: 1
queueCapacity: 1
ratelimiter:
instances:
backendA:
limitForPeriod: 10
limitRefreshPeriod: PT1S
timeoutDuration: 0
eventConsumerBufferSize: 100
backendB:
limitForPeriod: 6
limitRefreshPeriod: PT0.5S
timeoutDuration: PT3S
You can also override the default configuration, define shared configurations and overwrite them in Ratpack's application.yml
config file.
For example:
resilience4j:
circuitbreaker:
configs:
default:
ringBufferSizeInClosedState: 100
ringBufferSizeInHalfOpenState: 10
waitDurationInOpenState: 10000
failureRateThreshold: 60
eventConsumerBufferSize: 10
someShared:
ringBufferSizeInClosedState: 50
ringBufferSizeInHalfOpenState: 10
instances:
backendA:
baseConfig: default
waitDurationInOpenState: 5000
backendB:
baseConfig: someShared
Annotations
The Ratpack library provides annotations and AOP Aspects which are auto-configured.
RateLimiter, Retry, CircuitBreaker and Bulkhead annotations support synchronous return types, asynchronous types like CompletableFuture, and reactive types like Raptack's Promise and Spring Reactor's Flux and Mono.
Bulkhead annotation has now type attribute the define which bulkhead implementation will be used , by default it is semaphore but if you can switch to thread pool type by setting the type attribute in the annotation:
@Bulkhead(name = BACKEND, type = Bulkhead.Type.THREADPOOL)
public CompletableFuture<String> doSomethingAsync() throws InterruptedException {
Thread.sleep(500);
return CompletableFuture.completedFuture("Test");
}
An example of all resilience4j supported AOP aspects:
@CircuitBreaker(name = BACKEND, fallbackMethod = "fallback")
@RateLimiter(name = BACKEND)
@Bulkhead(name = BACKEND)
@Retry(name = BACKEND, fallbackMethod = "fallback")
public Promise<String> method(String param1) {
return Promise.error(new NumberFormatException());
}
private Promise<String> fallback(String param1, IllegalArgumentException e) {
return Promise.just("test");
}
private Promise<String> fallback(String param1, RuntimeException e) {
return Promise.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.
You can define one global fallback method with an exception parameter only if multiple methods has the same return type and you want to define the same fallback method for them once and for all.
Events Endpoint
The emitted CircuitBreaker, Retry, RateLimiter and Bulkhead events are stored in a separate circular event consumer buffers. The size of an event consumer buffer can be configured in the application.yml file (eventConsumerBufferSize).
The endpoint /circuitbreaker/states
lists the state for of all CircuitBreaker instances. The endpoint /circuitbreaker/events
lists the event list of all CircuitBreaker instances. The events endpoint is also available for Retry, RateLimiter and Bulkhead.
For example:
{
"circuitBreakerEvents":[
{
"circuitBreakerName": "backendA",
"type": "ERROR",
"creationTime": "2019-01-10T15:39:17.117-05:00[America/Chicago]",
"errorMessage": "java.io.IOException: 500 This is a remote exception",
"durationInMs": 0
},
{
"circuitBreakerName": "backendA",
"type": "SUCCESS",
"creationTime": "2019-01-10T15:39:20.518-05:00[America/Chicago]",
"durationInMs": 0
},
{
"circuitBreakerName": "backendB",
"type": "ERROR",
"creationTime": "2019-01-10T15:41:31.159-05:00[America/Chicago]",
"errorMessage": "java.io.IOException: 500 This is a remote exception",
"durationInMs": 0
},
{
"circuitBreakerName": "backendB",
"type": "SUCCESS",
"creationTime": "2019-01-10T15:41:33.526-05:00[America/Chicago]",
"durationInMs": 0
}
]
}
Updated about 5 years ago