Redis的简单限流 Java源码实现

限流一般就是用在两个方面,一个是当系统的处理能力不够的时候,我们要阻止一些请求到达我们的系统就需要用到限流。另一个方面,当我们需要限制用户的行为的时候,我们也可以使用到限流。
首先我们考虑这么一个问题,如果让你来设计一个方法,他需要满足限制用户在一段时间内的某个行为,你会如何设计?进一步考虑,对于你设计的方法,你需要使用redis的哪种数据结构来进行实现?
对于接口,我们可以很清晰的设计出来。

//用户的某个行为在一段时间内是否被允许
public boolean isReqAllowed(String userUid, String method, Integer period, Integer maxReqCount){
	xxxxx
	sssss
	return xxx;
}

好了,现在我们已经设计出了方法,那么这个场景下redis的哪个数据结构适合来干这么一件事情呢?一段时间,又有限制的请求数,稍微刷过算法的都脱口而出了-----滑动窗口。没错,就是滑动窗口,而redis中实现滑动串口最适合的数据结构莫过于zset了。key可以是用户和某个行为拼接的串,而value可以是唯一性高的时间戳也可以是uuid,value在这里其实并没有什么特殊的意义。最重要的是score,这个是关键点。我们需要根据score来判断是否在滑动窗口内部,还要根据他来查看滑动窗口内部有多少的元素,综上所述时间戳无疑都是最好的选择。
附上Java代码

	@Autowired
    private RedisTemplate<String,String> redisTemplate;
    
    public boolean isReqAllowed(String userUid, String method, Integer period, Integer maxReqCount){
        String key = String.format("histrix:%s:%s",userUid,method);
        long nowTime = System.currentTimeMillis();
        //先将请求添加进zset里面去,然后将滑动窗口之外的请求都删除掉,再将zset的元素个数得到于我们的最大阈值进行对比返回结果
        redisTemplate.opsForZSet().add(key,""+nowTime,nowTime);
        redisTemplate.opsForZSet().remove(key,0,nowTime - period*1000);
        Long count = redisTemplate.opsForZSet().size(key);
        if(count == null)return true;
        return maxReqCount >= count;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值