https://github.com/resilience4j/resilience4j
resilience4j will be a prominent implementation of Circuit Breaker, primarily for Java. Rate-Limiting related features also exist.
https://github.com/resilience4j/resilience4j#ratelimiter
In the following, verification is performed based on the following sample program.
https://github.com/resilience4j/resilience4j-spring-boot2-demo
Configuration build.gradle
When linking with Spring Boot, use ʻio.github.resilience4j: resilience4j-spring-boot2`.
dependencies {
compile('org.springframework.boot:spring-boot-starter-webflux')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-aop')
compile("io.github.resilience4j:resilience4j-spring-boot2:${resilience4jVersion}") // <-
application.yml
resilience4j.ratelimiter:
configs:
default:
registerHealthIndicator: false
limitForPeriod: 3
limitRefreshPeriod: 2s
timeoutDuration: 0
eventConsumerBufferSize: 100
instances:
backendA:
baseConfig: default
backendB:
limitForPeriod: 6
limitRefreshPeriod: 500ms
timeoutDuration: 3s
With limitForPeriod: 3
and limitRefreshPeriod: 2s
, Rate-Limitting is performed if there are more than 3 accesses within 2 seconds.
Java Set @RateLimiter annotation in the process to set Rate-Limitting.
@Override
@RateLimiter(name = BACKEND_A) // <--
@CircuitBreaker(name = BACKEND_A)
@Bulkhead(name = BACKEND_A)
@Retry(name = BACKEND_A)
public String success() {
return "Hello World from backend A";
}
Running With this setting, a 500 error will be returned if you access more than 3 times in 2 seconds.
< HTTP/1.1 200 OK
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 26
<
* Connection #0 to host localhost left intact
Hello World from backend A
< HTTP/1.1 500 Internal Server Error
< Content-Type: application/json
< Content-Length: 235
<
{
"timestamp" : "2020-05-05T09:23:13.530+0000",
"path" : "/backendA/success",
"status" : 500,
"error" : "Internal Server Error",
"message" : "RateLimiter 'backendA' does not permit further calls",
"requestId" : "b372ed49"
}
Internally, a RuntimeException called RequestNotPermitted
occurs, so it is necessary to perform appropriate error handling and HTTP StatusCode return processing in the Controller layer.
Monitoring
You can get the setting contents related to Rate-Limit with / actuator / ratelimiters
.
{
"rateLimiters" : [ "backendA", "backendB" ]
}
Conclusion
With resilience4j and resilience4j-spring-boot2, it's fairly easy to add Rate-Limiting functionality to your existing Spring Boot applications.
The difference from bucket4j is that URL Path and rate-Limiting processing for each user are not supported by default.
If you want to apply Rate-Limiting processing to the entire system in earnest, it is preferable to introduce API Gateway middleware using Ambassador Pattern or Side-Car Pattern.
Recommended Posts