系统环境:CentOS 7.6 Docker CE 19.03.9
Redis4.0 开始提供了一个 Redis-Cell 模块,这个模块使用漏斗算法,提供了一个非常好用的限流指令。 漏斗算法就像名字一样,是一个漏斗,请求从漏斗的大口进,然后从小口出进入到系统中,这样,无论 是多大的访问量,最终进入到系统中的请求,都是固定的。 使用漏斗算法,需要我们首先安装 Redis-Cell 模块: https://github.com/brandur/redis-cell
手动安装
安装步骤:
wget https://github.com/brandur/redis-cell/releases/download/v0.2.4/redis-cell-v0.2.4-x86_64-unknown-linux-gnu.tar.gz
tar -zxvf redis-cell-v0.2.4-x86_64-unknown-linux-gnu.tar.gz
mkdir redis-cell
mv libredis_cell.d ./redis-cell
mv libredis_cell.so ./redis-cell
接下来修改 redis.conf 文件,加载额外的模块:
loadmodule /root/redis-5.0.7/redis-cell/libredis_cell.so
然后,启动 Redis:
redis-server redis.conf
redis 启动成功后,如果存在 CL.THROTTLE 命令,说明 redis-cell 已经安装成功了。
CL.THROTTLE 命令一共有五个参数
- 第一个参数是 key
- 第二个参数是漏斗的容量 3. 时间窗内可以操作的次数 4. 时间窗
- 每次漏出数量 执行完成后,返回值也有五个:
- 第一个 0 表示允许,1表示拒绝
- 第二个参数是漏斗的容量
- 第三个参数是漏斗的剩余空间
- 如果拒绝了,多长时间后,可以再试
- 多长时间后,漏斗会完全空出来
Docker安装
docker search redis-cell
docker pull hsz1273327/redis-cell
docker run -d -p 6379:6379 --name redis hsz1273327/redis-cell:latest
测试
pulish-key 15 20 10 1
15 是桶的容量 -- 即同时能存在多少个令牌
20 就是速率限制了
10 单位时间(s)
1 一次取出几个令牌, 默认是一
命令返回值
127.0.0.1:6379>cl.throttle user_id:api 15 20 10 1
1) "0" // 0是允许, 1是拒绝
2) "16" // 桶容量
3) "15" // 剩余令牌
4) "-1" // 拒绝的话需要等待多长时间再试(这就很贴心了)
5) "0" // 多长时间令牌放满
Java端调用
Lettuce扩展 首先定义一个命令接口:
public interface RedisCommandInterface extends Commands {
@Command("CL.THROTTLE ?0 ?1 ?2 ?3 ?4")
List<Object> throttle(String key, Long init, Long count, Long period, Long
quota); }
定义完成后,接下来,直接调用即可:
public class ThrottleTest {
public static void main(String[] args) {
RedisClient redisClient =
RedisClient.create("redis://{连接redis密码}@IP地址");
StatefulRedisConnection<String, String> connect = redisClient.connect();
RedisCommandFactory factory = new RedisCommandFactory(connect);
RedisCommandInterface commands =
factory.getCommands(RedisCommandInterface.class);
List<Object> list = commands.throttle("publish-key", 10L, 10L, 60L,
1L); }
}
System.out.println(list);
参考:限流功能的实现
注意:本文归作者所有,未经作者允许,不得转载