resilience4j-ratelimiter 接口限速器

简介

Rate Limiter 是 Resilience4j 提供的一个重要组件,用于限制对资源(如API接口)的访问速率,以确保系统的高可用性和可靠性。Rate Limiter 通过控制单位时间内允许通过的请求数量来防止系统过载。本文将详细介绍如何在Java中使用Resilience4j的Rate Limiter。

内部机制

Resilience4j的Rate Limiter将自纪元开始以来的所有纳秒分成周期,每个周期的持续时间由RateLimiterConfig.limitRefreshPeriod配置。在每个周期开始时,Rate Limiter会设置该周期内允许的活跃权限数(RateLimiterConfig.limitForPeriod)。

Resilience4j提供了两种Rate Limiter实现:

  1. AtomicRateLimiter:通过AtomicReference管理状态,其内部状态(State)是完全不可变的,包含activePermissions(最后一次调用后剩余的可用权限数,如果某些权限被预留,则可能为负数)。
  2. SemaphoreBasedRateLimiter:使用Semaphores和调度器,在每个limitRefreshPeriod后刷新权限。

创建和配置RateLimiter

创建RateLimiterRegistry

类似于CircuitBreaker模块,RateLimiter模块也提供了一个内存中的RateLimiterRegistry,用于管理(创建和检索)RateLimiter实例。

 

java

代码解读

复制代码

RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.ofDefaults();

自定义全局RateLimiterConfig

你可以通过RateLimiterConfig构建器来创建自定义的全局配置。

 

java

代码解读

复制代码

RateLimiterConfig config = RateLimiterConfig.custom() .limitRefreshPeriod(Duration.ofMillis(1)) // 刷新周期 .limitForPeriod(10) // 每周期允许的最大请求数 .timeoutDuration(Duration.ofMillis(25)) // 请求超时时间 .build(); // 使用自定义配置创建Registry RateLimiterRegistry registryWithCustomConfig = RateLimiterRegistry.of(config);

创建RateLimiter实例

通过Registry可以创建和检索RateLimiter实例。

这边整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】免费获取

java

代码解读

复制代码

RateLimiter rateLimiterWithDefaultConfig = registryWithCustomConfig.rateLimiter("name1"); // 使用默认配置 RateLimiter rateLimiterWithCustomConfig = registryWithCustomConfig.rateLimiter("name2", config); // 使用自定义配置

使用RateLimiter

装饰并执行功能接口

你可以使用RateLimiter来装饰任何可调用的方法或操作,限制其调用频率。

 

java

代码解读

复制代码

// 假设有一个BackendService类,其中有一个doSomething方法 BackendService backendService = new BackendService(); // 使用RateLimiter装饰doSomething方法 CheckedRunnable restrictedCall = RateLimiter.decorateCheckedRunnable(rateLimiterWithCustomConfig, backendService::doSomething); // 执行操作,并处理异常情况 Try.run(restrictedCall) .andThenTry(restrictedCall) .onFailure(RequestNotPermitted.class, throwable -> LOG.info("Wait before calling it again :)"));

修改RateLimiter参数

在运行时,你可以修改RateLimiter的某些参数,如超时时间和每周期的请求限制数。

 

java

代码解读

复制代码

rateLimiterWithCustomConfig.changeTimeoutDuration(Duration.ofMillis(50)); // 修改超时时间 rateLimiterWithCustomConfig.changeLimitForPeriod(20); // 修改每周期的限制数

请注意,新的超时时间不会影响当前正在等待权限的线程,新的每周期限制数将从下一个周期开始应用。

监听事件

RegistryEvents

你可以注册事件监听器来响应RateLimiterRegistry中的事件(如RateLimiter的添加、替换或删除)。

 

java

代码解读

复制代码

registryWithCustomConfig.getEventPublisher() .onEntryAdded(entryAddedEvent -> LOG.info("RateLimiter {} added", entryAddedEvent.getAddedEntry().getName())) .onEntryRemoved(entryRemovedEvent -> LOG.info("RateLimiter {} removed", entryRemovedEvent.getRemovedEntry().getName()));

RateLimiterEvents

RateLimiter会发出包含成功获取权限或获取失败信息的事件流。你可以注册为事件消费者来消费这些事件。

 

java

代码解读

复制代码

// 使用RxJava或其他响应式编程库来转换EventPublisher为Reactive Stream

Spring 项目集成 ratelimiter 实战

注册

 

java

代码解读

复制代码

@SpringBootApplication public class demoApplication { // 其他代码... @Bean("secondLismiter") public RateLimiter perSecondLimiter() { return RateLimiterRegistry.ofDefaults().rateLimiter("second-limiter", RateLimiterConfig.custom() .timeoutDuration(Duration.ofSeconds(5)) .limitForPeriod(15) // 每秒 15 次 .limitRefreshPeriod(Duration.ofSeconds(1)) .build()); } @Bean("minuteLimiter") public RateLimiter perMinuteLimiter() { return RateLimiterRegistry.ofDefaults().rateLimiter("minute-limiter", RateLimiterConfig.custom() .timeoutDuration(Duration.ofSeconds(5)) .limitForPeriod(5000) // 每分 5000 次数 .limitRefreshPeriod(Duration.ofMinutes(1)) .build()); } // 其他代码... }

使用

 

java

代码解读

复制代码

@Resource(name = "SecondLimiter") private RateLimiter secondLimiter; @Resource(name = "minuteLimiter") private RateLimiter minuteLimiter; public DemoController() { @RequestMapping("/demo/test") @ResponseBody public void test() { // 其他代码... // 分、秒限流器剩余可用次数 LOG.info("分限流器可用次数:" + secondLimiter.getMetrics().getAvailablePermissions()); LOG.info("秒限流器可用次数:" + minuteLimiter.getMetrics().getAvailablePermissions()); // 限流器校验请求 if (secondLimiter.acquirePermission() && minuteLimiter.acquirePermission(toList.length)) { // 执行通过请求 // DEMO } else { // 打印限流请求 // LOG.warn("") } // 其他代码... } }

总结

Resilience4j的RateLimiter是一个功能强大的工具,用于限制对系统资源的访问速率,从而保护系统免受过载和拒绝服务攻击。通过自定义配置和灵活的API,你可以轻松地将其集成到你的Java应用程序中,并确保服务的高可用性和可靠性。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Resilience4j-cache 是一个基于 Resilience4j 的缓存库,提供了对缓存的重试、熔断和限流等功能。它可以很方便地与 Spring Boot 集成使用。 以下是使用 Resilience4j-cache 的步骤: 1. 添加依赖 在 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-cache</artifactId> <version>1.7.0</version> </dependency> ``` 2. 配置缓存 在 Spring Boot 的配置文件中添加以下配置: ``` resilience4j.cache.caffeine.instances.myCache.maximum-size=1000 resilience4j.cache.caffeine.instances.myCache.expire-after-write=5s ``` 该配置表示创建一个名为 `myCache` 的缓存,最大容量为 1000,写入后 5 秒过期。 3. 创建缓存 在代码中创建缓存实例: ``` Cache<String, String> cache = Cache.of("myCache", CacheConfig .custom() .expireAfterWrite(Duration.ofSeconds(5)) .maximumSize(1000) .build() ); ``` 4. 使用缓存 使用 `cache.get(key, loader)` 方法获取缓存项,如果缓存不存在,则会调用 `loader` 方法加载数据。 ``` String value = cache.get("key", () -> { // 从数据库或其他地方加载数据 return "value"; }); ``` 5. 配置重试、熔断和限流 可以使用 Resilience4j 提供的 `Retry`、`CircuitBreaker` 和 `RateLimiter` 等组件对缓存进行重试、熔断和限流等操作。 例如,使用 `Retry` 组件对缓存进行重试操作: ``` Cache<String, String> cache = Cache.of("myCache", CacheConfig .custom() .expireAfterWrite(Duration.ofSeconds(5)) .maximumSize(1000) .build() ); Retry retry = Retry.ofDefaults("retry"); Function<String, String> decorated = Retry.decorateFunction(retry, cache::get); String value = decorated.apply("key"); ``` 以上就是使用 Resilience4j-cache 的基本步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值