package com.zxl.redis.rediscode;
import redis.clients.jedis.Jedis;
import java.util.List;
/**
* @author xiaoliang
* @date 2020/5/12 21:30
* @since V1.0
*/
public class LoginValidate {
//设置成10s是因为方便测试
//周期时间为毫秒
final static int EXPIRE_TIME_MILLISECOND = 10*1000;
//一个周期内最多的操作次数
final static int MOST_TIMES_IN_TIME_LIMIT = 5;
public static void main(String[] args) {
//创建Jedis客户端
Jedis jedis = new Jedis("192.168.0.3",6379);
//操作数据
jedis.select(0);
//模拟登入用户
String userId="zxl";
loginValidateWithQueue(jedis,userId);
loginValidateWithQueue(jedis,userId);
loginValidateWithQueue(jedis,userId);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
loginValidateWithQueue(jedis,userId);
loginValidateWithQueue(jedis,userId);
loginValidateWithQueue(jedis,userId);
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
loginValidateWithQueue(jedis,userId);
loginValidateWithQueue(jedis,userId);
//取出用户最后五次的操作时间
List<String> values=jedis.lrange(userId,0,-1);
for (int i = 0; i < values.size(); i++) {
System.out.printf(values.get(i) + "\n");
}
//删除用户列表
jedis.del(userId);
jedis.close();
}
/**
* 用Redis和任意语言实现一段恶意登录保护的代码,限制1小时内每用户Id最多只能登录5次
*
* @param jedis
* @param userId
* @return
*/
public static boolean loginValidateWithQueue(Jedis jedis, String userId) {
Long currentTime = System.currentTimeMillis();
//判断List列表长度是否超过操作次数
if (jedis.llen(userId) < MOST_TIMES_IN_TIME_LIMIT) {
//将当前操作时间放入到用户list中
jedis.rpush(userId, currentTime.toString());
System.out.println(currentTime + " 登入成功!" + jedis.llen(userId));
return true;
} else {
//如果超过操作次数则取出list中最早操作时间,即list下标为0的
String earliestTimeStr = jedis.lindex(userId, 0);
//将字符串转为长整形
Long earliestTime = Long.valueOf(earliestTimeStr);
//判断最早操作时间是否在周期内,如果在周期内说明在这个周期内操作数已到阀值不允许再操作。
if (currentTime - earliestTime <= EXPIRE_TIME_MILLISECOND) {
System.out.println(EXPIRE_TIME_MILLISECOND/1000 + " 秒内只能操作" + MOST_TIMES_IN_TIME_LIMIT + " 次");
return false;
} else {
//如果最早操作时间不再周期,说明可以继续操作。
//为了使用户列表长度为操作次数。需要删除最早的操作时间,保存本次操作时间。
//删除列表尾段数据,即最早操作时间。
jedis.lpop(userId);
//插入当前操作时间
jedis.rpush(userId, currentTime.toString());
System.out.println(currentTime + " 登入成功!" + jedis.llen(userId));
return true;
}
}
}
}
Redis限制N小时内每用户Id最多只能登录M次解决方案
最新推荐文章于 2022-08-25 11:17:21 发布