redis限流使用lua脚本

/**
     * lua脚本,计数器限流
     * 5秒内限流10次
     * @param key
     * @return
     */
    public boolean acquire(String key) {
        long now = System.currentTimeMillis();
        String KEY_PREFIX = "limiter_";
        String QPS = "10"; //限流次数
        Long time = 5000L; //时间
        String ttl = "60"; 
        key = KEY_PREFIX + key;
        String oldest = String.valueOf(now - time);
        String score = String.valueOf(now);
        String scoreValue = score;
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        redisScript.setResultType(Long.class);
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("limiter2.lua")));
        Long result = stringRedisTemplate.execute(redisScript, Arrays.asList(key), oldest, score, QPS, scoreValue, ttl);
        return result.intValue() == 1;
    }

lua脚本,limiter2.lua

--KEYS[1]: 限流 key
--ARGV[1]: 时间戳 - 时间窗口
--ARGV[2]: 当前时间戳(作为score)
--ARGV[3]: 阈值
--ARGV[4]: score 对应的唯一value
--ARGV[5]: 失效时间
-- 1. 移除时间窗口之前的数据
redis.call('zremrangeByScore', KEYS[1], 0, ARGV[1])
-- 2. 统计当前元素数量
local res = redis.call('zcard', KEYS[1])
-- 3. 是否超过阈值
if (res == nil) or (res < tonumber(ARGV[3])) then
    redis.call('zadd', KEYS[1], ARGV[2], ARGV[4])
    --设置过期时间,防止冷用户持续占用内存,
    -- 过期时间应该是时间窗口长度+失效时间
    redis.call("expire",KEYS[1],ARGV[5]);
    return 1
else
    return 0
end

在拦截其中,对需要限流的接口调用acquire方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值