概述

resilience4j-ratelimiter 可以用来控制指定时间内的请求数量,从而保证服务的可靠性。

比如,我们调用的第三方接口(如百度api,face++)通常会有流量的限制,此时,我们可以通过resilience4j控制流量。

当流量超过限制时,可以直接抛弃,也可以放入等待队列中。

RateLimiter的默认实现是AtomicRateLimiter,通过AtomicReference来管理状态, AtomicRateLimiter.State是不可修改的,它有如下属性:

  • activeCycle: 上次调用占用的周期数,活跃周期数
  • activePermissions:剩余的令牌数,当一个调用占用多个周期时,可能为负数。
  • nanosToWait:获取令牌等待时间

在这里插入图片描述
另外也有一个通过信号量控制流量的实现SemaphoreBasedRateLimiter

参数说明

属性 默认值 说明
timeoutDuration 5[s] 线程等待令牌的时间
limitRefreshPeriod 500[ns] 令牌刷新周期,每次刷新,剩余令牌数都恢复到默认值
limitForPeriod 50 每个周期的初始令牌数

通过代码配置

//限制每秒10次调用
RateLimiterConfig config = RateLimiterConfig.custom()
  .limitRefreshPeriod(Duration.ofSeconds(1))
  .limitForPeriod(10)
  .timeoutDuration(Duration.ofMillis(25))
  .build();
// Create registry
RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config);

// Use registry
RateLimiter rateLimiterWithDefaultConfig = rateLimiterRegistry
  .rateLimiter("name1");
// Decorate your call to BackendService.doSomething()
CheckedRunnable restrictedCall = RateLimiter
    .decorateCheckedRunnable(rateLimiterWithDefaultConfig, backendService::doSomething);
Try.run(restrictedCall)
    .onFailure((RequestNotPermitted throwable) -> LOG.info("Wait before call it again :)"));

除了可以封装 CheckedRunnable,还可以封装Callable、Supplier、Runnable、Consumer、CheckedSupplier、CheckedConsumer、CompletionStage类型。

spring注解实现流控

application.yml

resilience4j.ratelimiter:
    instances:
        backendA:
            limitForPeriod: 10
            limitRefreshPeriod: 1s
            timeoutDuration: 0
            registerHealthIndicator: true
            eventConsumerBufferSize: 100
        backendB:
            limitForPeriod: 6
            limitRefreshPeriod: 500ms
            timeoutDuration: 3s

代码:

@RateLimiter(name = "backendA",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");
}

与Feign集成

依赖:

   <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring-boot2</artifactId>
            <version>1.6.1</version>
        </dependency>
@FeignClient(name = "x")
interface TestClient {
    @GetMapping("/test1")
    @RateLimiter(name = "x", fallbackMethod = "m1")
    String test1();

    @GetMapping("/test2")
    @RateLimiter(name = "x", fallbackMethod = "m2")
    String test2();

    default String m1(Exception e){
        // ....
        return "x";
    }

    default String m2(Exception e){
        // ....
        return "x";
    }
}

更多

spring cloud resilience4j-retry 重试
spring cloud resilience4j - Bulkhead 线程隔离 并发控制
spring cloud Resilience4j - 熔断器 CircuitBreaker
spring cloud resilience4j - RateLimiter 流控

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。