美文网首页
Redis + lua 限流

Redis + lua 限流

作者: 山间草夫 | 来源:发表于2020-12-04 11:31 被阅读0次

lua脚本

local key_local = redis.call('setnx',KEYS[1],0)
if tonumber(key_local) == 0 then
    if tonumber(redis.call('get',KEYS[1]))>=tonumber(ARGV[2]) then
        return false
    else
        redis.call('incr',KEYS[1])
        return true
    end
else
    redis.call('incr',KEYS[1])
    redis.call('pexpire',KEYS[1],ARGV[1])
    return true
end

java 代码:

package com.feinno.ssp.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Collections;

/**
 * redis + lua 限流策略
 */
@Component
public class FlowLimitComponent {
    @Autowired
    private StringRedisTemplate redisTemplate;
    DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();


    @PostConstruct
    private RedisScript<Boolean> loadRedisScript() {
        redisScript.setLocation(new ClassPathResource("lua/limit.lua"));
        redisScript.setResultType(Boolean.class);
        return redisScript;
    }


    /**
     * * 针对某个key使用lua脚本进行限流
     * * 使用lua优点,可以保证多个命令是一次行传输到Redis服务器并且是串行执行的,保证串行执行的命令中不行插入其他命令,防止并发问题
     * * 步骤:
     * * 1、判断key是否存在,如果不存在,保存该key,设置值为1,设置多少毫秒(n)最多进行几次(m)
     * * 2、如果值存在,先判断key是否超时了,如果超时则删除,并重新执行步骤1,如果key未超时,则判断是否超过n毫秒最多m次的限制
     *
     * @param key      redis key
     * @param mlitimes key 的时间
     * @param maxCount 该key 的最大流量
     * @return 返回true 表示放行
     */
    public Boolean noLimit(String key, long mlitimes, long maxCount) {
        return redisTemplate.execute(redisScript, Collections.singletonList(key), String.valueOf(mlitimes), String.valueOf(maxCount));
    }
}

相关文章

网友评论

      本文标题:Redis + lua 限流

      本文链接:https://www.haomeiwen.com/subject/oqgbwktx.html