(1)下载安装包
https://github.com/brandur/redis-cell/releases
(2)解压到某个目录
(3)进入 redis-cli,执行命令module load /aaa/bbb/libredis_cell.so
这是临时的办法,重启redis就没了
(4)想永久的,需要这样
$ redis-server --loadmodule /aaa/bbb/libredis_cell.so
加到启动命令里。
(5)进入 redis-cli,执行命令,可以看看是否生效。
127.0.0.1:6379> command info CL.THROTTLE
1) 1) "cl.throttle"
2) (integer) -1
3) 1) write
4) (integer) 1
5) (integer) 1
6) (integer) 1
127.0.0.1:6379> MODULE LIST
1) 1) "name"
2) "redis-cell"
3) "ver"
4) (integer) 1
(6)然后不停的执行类似这样的命令就行了:
CL.THROTTLE test 10 5 60 1
初始是10个令牌,每60秒允许5个。
多执行几次,就返回1拒绝了。
127.0.0.1:6379> CL.THROTTLE test 10 5 60 1
1) (integer) 0
2) (integer) 11
3) (integer) 4
4) (integer) -1
5) (integer) 0
1: 是否成功,0:成功,1:拒绝
2: 令牌桶的容量,大小为初始值+1
3: 当前令牌桶中可用的令牌
4: 若请求被拒绝,这个值表示多久后才令牌桶中会重新添加令牌,单位:秒,可以作为重试时间
5: 表示多久后令牌桶中的令牌会存满
=================================================
java中调用~~
(1)pom引入lettuce
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
注意,它会引入netty的一些包,如果你已经有netty了,注意排除,以免冲突。
(2)写一个command接口
package com.xxx.util;
import java.util.List;
import io.lettuce.core.dynamic.Commands;
import io.lettuce.core.dynamic.annotation.Command;
public interface RedisCommandInterface extends Commands {
/**
* 限流,如CL.THROTTLE test 10 5 60 1
* <p>
* test是key名字,初始10个令牌,每60秒允许使用5个令牌,本次获取一个令牌
* <p>
* 127.0.0.1:6379> CL.THROTTLE test 10 5 60 1
* <p>
* 1) (integer) 0 0成功,1拒绝
* <p>
* 2) (integer) 11 令牌桶的容量
* <p>
* 3) (integer) 10 当前令牌桶中可用的令牌
* <p>
* 4) (integer) -1 若请求被拒绝,这个值表示多久后才令牌桶中会重新添加令牌,单位:秒,可以作为重试时间
* <p>
* 5) (integer) 12 表示多久后令牌桶中的令牌会存满
*
* @param name
* @param initCapactiy
* @param operationCount
* @param secondCount
* @param getCount
* @return
*/
@Command("CL.THROTTLE ?0 ?1 ?2 ?3 ?4")
List<Object> throttle(String key, long initCapactiy, long operationCount, long secondCount, long getCount);
}
(3)然后调用即可
package com.xxx.util;
import java.util.List;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.dynamic.RedisCommandFactory;
public class RedisUtil {
private static RedisClient redisClient = null;
private static StatefulRedisConnection<String, String> conn = null;
private static RedisCommandInterface commands;
private static long initCapactiy = 20;
private static long operationCount = 20;
private static long secondCount = 1;
private static long getCount = 1;
static {
// 创建连接(会自动重连)
redisClient = RedisClient.create("redis://xxxx@127.0.0.1:6379/0");
conn = redisClient.connect();
// 获取Command
RedisCommandFactory factory = new RedisCommandFactory(conn);
commands = factory.getCommands(RedisCommandInterface.class);
}
public static boolean isAllowQuery(String name) {
//最多等两次
for(int i=0;i<3;i++) {
List<Object> resultList = commands.throttle(name, initCapactiy, operationCount, secondCount, getCount);
if (resultList.get(0).toString().equals("0")) {
return true;
}
//睡半秒
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("fail,"+name);
return false;
// Luna脚本不认这个命令
// RedisCommands<String, String> cmds = conn.sync();
// List<String> resultList = cmds.eval(" return redis.call('CL.THROTTLE test 10
// 5 60 1') ",ScriptOutputType.MULTI);
//
}
}
来源:CSDN
作者:rlk512974883
链接:https://blog.csdn.net/rlk512974883/article/details/103928569