使用 Resilience4j 的 RateLimiter 进行速率限制

resilience4j是一个主要针对Java的著名断路器实现。它还具备与速率限制相关的功能。

我们在以下基础上进行验证的是下方的示例程序。

配置

通过使用 build.gradle 文件构建

如果要将Spring Boot与Resilience4j集成,则使用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}") // <-

应用配置文件.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

当限制周期为2秒且在此期间内访问次数超过3次时,将进行速率限制。

Java:Java是一种面向对象的编程语言,具有简单、可移植、可扩展和高性能等特点。

在设置速率限制的处理中,设置@RateLimiter注解。

    @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";
    }

奔跑

根据本次设定,如果在2秒内进行超过3次的访问,将返回500错误。

两百的普通时间

< 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

速率限制时(500)

< 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"
}

内部有 RuntimeException 引发 RequestNotPermitted,因此在控制器层等需要适当处理错误和返回适当的 HTTP 状态码的处理。

监控

可以使用/actuator/ratelimiters来获取与速率限制相关的配置信息。

{
  "rateLimiters" : [ "backendA", "backendB" ]
}

结论

使用resilience4j和resilience4j-spring-boot2,在现有的Spring Boot应用程序中轻松添加速率限制功能。

与bucket4j的不同之处在于它不支持URL路径或基于用户的速率限制处理。

如果要在系统中全面应用Rate-Limiting处理的话,我认为最好是使用Ambassador Pattern或Side-Car Pattern来引入API Gateway的中间件。

广告
将在 10 秒后关闭
bannerAds