RateLimiter限流简单介绍

限流:控制单位时间内的请求次数,避免过高的请求造成系统压力,保证服务的稳定性和可靠性。
QPS(Queries Per Second)系统每秒能够处理请求的查询次数

常见的算法:

  • 固定窗口算法(计数器算法)

每一个固定单位时间为一个窗口,记录每个时间窗口请求数量,数量达到阈值拒绝请求等待下一个时间窗口
问题场景:存在时间窗口内的某一瞬间出现大量请求导致后面较长的时间内无法处理请求

//采用Redis简单实现
Long times= redisTemplate.opsForValue().increment(key);
//第一次自增设置过期时间,避免每次自增都更新过期时间
if (Objects.nonNull(times) && value == 1) {
    redisTemplate.expire(key, duration);
}
 Assert.isTrue(times < 10, "时间窗口内请求次数较多!");
  • 滑动窗口算法

将时间窗口划分为更小的时间片段,相邻几个时间片段组成一个时间窗口,当时间窗口求情数量达到阈值拒绝请求。
在这里插入图片描述
优点:只要时间片段划分更细就可以避免固定时间窗口请求突增的问题
问题场景:需要维护多个时间片段,增加存储开销

  • 令牌桶算法

令牌以固定的速率生产令牌并放入桶中直到达到桶的最大值,每一个请求先去桶中获取令牌,没有获取到令牌则拒绝请求。
优点:能够平滑的处理突发流量,突发的最大请求数就是令牌桶当前拥有的令牌数。
在这里插入图片描述

Guava的RateLimiter就是令牌桶算法

//创建限流器(设置每秒生成5个令牌)
RateLimiter rateLimiter = RateLimiter.create(5,Duration.ofMillis(5));

这里设置了一个5分钟的预热,预热的意思是指当重新设置了令牌的生成速率后,令牌的生成速率不会立马改变而是有一个预热过程,预热时间结束才会以新的速率生成令牌。

//重新设置令牌生成速率为每秒10个令牌
rateLimiter.setRate(10);

guava中的RateLimiter令牌桶没有一个固定的容量,是通过计算上一次请求到当前请求这个时间段能否生成满足当前请求的令牌数,不满足则会继续等待(有一个等待的超时时间设置,默认是超时时间是0),如果超时则拒绝请求。

//这里设置当前请求需要5个令牌,超时时间为60秒
rateLimiter.tryAcquire(5,Duration.ofSeconds(60));

当并发请求时会根据调用尝试获取令牌的顺寻来执行获取令牌
在这里插入图片描述

  • 漏桶算法

请求到来之后直接放入桶中,桶满则拒绝请求,桶内按恒定的速率流出请求。
在这里插入图片描述
就像请求先放入队列,然后以恒定的速度处理请求,所以并发请求不友好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值