问题背景:5 分钟内最多允许用户尝试登录 3 次,如果错误次数超过限制,需要对该用户进行锁定。如何实现?
我:滑动窗口,是一个什么样的概念?
师兄A:在一段时间内,它可以限制你就是用来限流的一样的。
师兄B:因为他我刚开始想的是设定一些常量,比如说最大的常识次数三次,然后锁定时间五分钟。但是它这里面就是存在一种情况就是在五分钟之内我登了两,我只登尝试两次。我相信大大家可能遇见过这种情况。就比如说登录银行密码的时候,密码老记错。他就跟你说五分钟之内你只能尝试三次,你只剩一次机会了?
那这个时候你不能在五分钟,你不用再在五分钟之内尝试第三次。比如说到了五分钟之后的第一秒,你再去尝试。
我:对
师兄B:再去尝试的话,这样的就会是不是有三个时间点就两个在五分钟之内,两个在下一个五分钟之内。这时候就要淘汰远的那个五分钟就是只剩两个。
我:是的
师兄B:那相当于它进入到下一个窗口期了,上在窗口期里面,你就能发生三次,像只要这个窗口期是这个窗口的,它是滑动的,永远都是五分钟的一个限制。
最终的代码实现如下:
public boolean login(String username, String password) {
String attemptsKey = "login_attempts:" + username;
String lockedKey = "locked:" + username;
long attempts = redis.get(attemptsKey);
if (attempts > 3) {
if (redis.exists(lockedKey)) {
return false; // 用户被锁定
} else {
// 锁定用户 5 分钟
redis.set(lockedKey, "true", 5 * 60);
return false;
}
}
if (validatePassword(username, password)) {
// 重置计数器和锁定标志
redis.del(attemptsKey);
redis.del(lockedKey);
return true;
} else {
// 增加尝试次数
redis.incr(attemptsKey);
return false;
}
}