本文主要是介绍How to ratelimit by resilience4j,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 特点
- Resilience4j-Bulkhead
- Semaphore模式
- FixedThreadPool模式
- Resilience4j-RateLimiter
- 令牌桶算法默认实现 AtomicRateLimiter
- 信号量实现 SemaphoreBasedRateLimiter
- Talk is Cheap,Show you the code
特点
- 支持jdk8函数式编程
- 轻量级,易于使用的编程API
- 模块化设计,将每个功能点(如熔断、限速器、自动重试)都拆成了单独的模块,使用时只需要引入相关依赖即可。
- 使用装饰器模式对任何函数或lamda表达式进行增强。
缺点:
- 缺乏生产级别的配套设施(如提供规则管理和实时监控能力的控制台)
- 文档不够详细
与hystrix对比:https://resilience4j.readme.io/docs/comparison-to-netflix-hystrix
Resilience4j-Bulkhead
Resilience4j提供了两种舱壁模式(Bulkhead),可用于限制并发执行的次数:
- SemaphoreBulkhead(信号量舱壁,默认),基于Java并发库中的Semaphore实现。
- FixedThreadPoolBulkhead(固定线程池舱壁),它使用一个有界队列和一个固定线程池。
Semaphore模式
属性配置 | 默认值 | 含义 |
---|---|---|
maxConcurrentCalls | 25 | 舱壁允许的最大并行执行量 |
maxWaitDuration | 0 | 尝试进入饱和舱壁时,应阻塞线程的最长时间。 |
FixedThreadPool模式
属性配置 | 默认值 | 含义 |
---|---|---|
queueCapacity | 100 | Configures the capacity of the queue. |
maxThreadPoolSize | Runtime.getRuntime().availableProcessors() | Configures the max thread pool size. |
keepAliveDuration | 20[ms] | When the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating. |
coreThreadPoolSize | Runtime.getRuntime().availableProcessors() - 1 | Configures the core thread pool size |
- 原理:
- FixedThreadPoolBulkhead使用一个固定线程池和一个等待队列来实现舱壁。
- 当线程池中存在空闲时,则此时进入系统的请求将直接进入线程池开启新线程或使用空闲线程来处理请求。
- 当线程池无空闲时接下来的请求将进入等待队列,若等待队列仍然无剩余空间时接下来的请求将直接被拒绝。
- 在队列中的请求等待线程池出现空闲时,将进入线程池进行业务处理。
Resilience4j-RateLimiter
ratelimiter是resilience4j的限流器,提供了一下两种限流器实现。参数如下:
属性配置 | 默认值 | 含义 |
---|---|---|
timeoutDuration | 5[s] | 等待获取许可时间 |
limitRefreshPeriod | 500 [ns] | 限流器刷新周期. |
limitForPeriod | 50 | 固定周期内的许可数. |
令牌桶算法默认实现 AtomicRateLimiter
将jvm启动开始和结束之间的时间划分为一个个的cycle周期,并设置cycle内即固定刷新周期内的许可数,当线程请求达到时获取当前周期内是否有允许的许可数被获取,有则执行,否则抛出异常。
信号量实现 SemaphoreBasedRateLimiter
当请求线程获取到信号量时执行业务逻辑方法,如果获取不到信号量,则在超时时间内阻塞,等待信号量被释放。系统会启动一个周期性线程池按固定周期(cycle),释放已经获取到信号量的线程。
源码相关如下:
private void scheduleLimitRefresh() {scheduler.scheduleAtFixedRate(this::refreshLimit,this.rateLimiterConfig.get().getLimitRefreshPeriod().toNanos(),this.rateLimiterConfig.get().getLimitRefreshPeriod().toNanos(),TimeUnit.NANOSECONDS);}void refreshLimit() {int permissionsToRelease =this.rateLimiterConfig.get().getLimitForPeriod() - semaphore.availablePermits();semaphore.release(permissionsToRelease);}
Talk is Cheap,Show you the code
import io.github.resilience4j.bulkhead.Bulkhead;
import io.github.resilience4j.bulkhead.BulkheadConfig;
import io.github.resilience4j.bulkhead.BulkheadRegistry;
import io.github.resilience4j.bulkhead.ThreadPoolBulkhead;
import io.github.resilience4j.bulkhead.ThreadPoolBulkheadConfig;
import io.github.resilience4j.bulkhead.ThreadPoolBulkheadRegistry;
import io.github.resilience4j.ratelimiter
这篇关于How to ratelimit by resilience4j的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!