Redis-Cell 漏斗限流的使用

(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://[email protected]: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);
        //

    }

}

扫描二维码关注公众号,回复: 11568871 查看本文章

猜你喜欢

转载自blog.csdn.net/rlk512974883/article/details/103928569