ruoyi 框架查询当前用户使用keys(*)问题解决

使用 keys() 在生产环境中会导致性能下降、阻塞其他请求、数据不一致、内存消耗过大和安全风险,因此在线上环境应避免使用,下面给出一种解决查询系统当前用户不适用keys()的方案

使用 Redis Set 数据结构实现

  • 将每个在线用户的唯一标识(如用户ID)存储在一个 Redis Set 中。
  • 当用户上线时,使用 SADD 将用户ID添加到 Set 中。
  • 当用户下线时,使用 SREM 将用户ID从 Set 中移除。
  • 为每个在线用户的唯一标识(如用户ID)设置一个TTL(过期时间)
  • 定期清理过期的用户。
  • 统计在线用户时,使用 key 命令获取 Set 中的元素,然后通过循环获取当前登录用户
#user1上线并设置TTL
SET user:user1:status online EX <ttl>
ZADD online_users_timestamp <timestamp> user1

#user2上线并设置TTL
SET user:user2:status online EX <ttl>
ZADD online_users_timestamp <timestamp> user2

代码实现

//登录时
redisTemplate.opsForSet().add(ALL_TOKENS_CACHE_KEY, value) //,存入key 进入set 集合

//查询时
Set<String> keys = redisTemplate.opsForSet().members(ALL_TOKENS_CACHE_KEY) // 读取set 集合中的所有key
for (String key : keys)
{
    LoginUser user = redisCache.getCacheObject(key); //循环读取登录用户
    //解决keys(*)时存入的Set<String> keys 中的key后期不知道是否过期的问题
    if (user == null) {
       redisCache.delCacheSetValue(ALL_TOKENS_CACHE_KEY, key);
       continue;
    }      
}

定时任务去除set中过期token

@Component
public class RemoveExpireToken {

	@Autowired
	private SessionRedisCache sessionRedisCache;

	public void remove() {

		Set<String> keys = sessionRedisCache.getCacheSet(ALL_TOKENS_CACHE_KEY);

		for (String key : keys) {
			LoginUser user = sessionRedisCache.getCacheObject(key);
			if (user == null) {
				sessionRedisCache.delCacheSetValue(ALL_TOKENS_CACHE_KEY, key);
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值