循环遍历获取 redis key实现在用户在线,性能不高,尤其是用户数量多的情况容易导致其他的redis线程卡死.这边用 redis hash维护一个现在用户,只要简单的实现用户同步就可以了.提交了性能

This commit is contained in:
金威正
2020-08-25 13:24:27 +08:00
committed by Gitee
parent fa5596bb20
commit 27c8d2b7f0
3 changed files with 80 additions and 32 deletions

View File

@ -1,9 +1,7 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
@ -42,39 +40,56 @@ public class SysUserOnlineController extends BaseController
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(String ipaddr, String userName) public TableDataInfo list(String ipaddr, String userName)
{ {
Collection<String> keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*"); // 一次性取出 在线用户
Map<String, Object> maps = redisCache.getCacheMap(Constants.LOGIN_TOKEN_KEY_ONLINE);
List<String> delList=new ArrayList<>();
List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>(); List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
for (String key : keys) Iterator<Map.Entry<String, Object>> it = maps.entrySet().iterator();
{ while(it.hasNext()){
LoginUser user = redisCache.getCacheObject(key); Map.Entry<String, Object> entry = it.next();
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) LoginUser user=(LoginUser) entry.getValue();
{ boolean removed = true;
if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) if (user.getExpireTime()<=System.currentTimeMillis()){
it.remove();
removed=false;
delList.add(entry.getKey());
}
if (removed){
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
{ {
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername()))
{
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
}
}
else if (StringUtils.isNotEmpty(ipaddr))
{
if (StringUtils.equals(ipaddr, user.getIpaddr()))
{
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
}
}
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
{
if (StringUtils.equals(userName, user.getUsername()))
{
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
}
}
else
{
userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
} }
} }
else if (StringUtils.isNotEmpty(ipaddr))
{ };
if (StringUtils.equals(ipaddr, user.getIpaddr()))
{
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
}
}
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
{
if (StringUtils.equals(userName, user.getUsername()))
{
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
}
}
else
{
userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
}
}
Collections.reverse(userOnlineList); Collections.reverse(userOnlineList);
userOnlineList.removeAll(Collections.singleton(null)); userOnlineList.removeAll(Collections.singleton(null));
if (!delList.isEmpty()){
String[] delTokens=new String[delList.size()];
redisCache.delCacheMapKey(Constants.LOGIN_TOKEN_KEY_ONLINE,delList.toArray(delTokens));
}
return getDataTable(userOnlineList); return getDataTable(userOnlineList);
} }
@ -86,7 +101,10 @@ public class SysUserOnlineController extends BaseController
@DeleteMapping("/{tokenId}") @DeleteMapping("/{tokenId}")
public AjaxResult forceLogout(@PathVariable String tokenId) public AjaxResult forceLogout(@PathVariable String tokenId)
{ {
redisCache.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId); redisCache.deleteObject(tokenId);
redisCache.delCacheMapKey(Constants.LOGIN_TOKEN_KEY_ONLINE , tokenId);
return AjaxResult.success(); return AjaxResult.success();
} }
} }

View File

@ -62,6 +62,12 @@ public class Constants
*/ */
public static final String LOGIN_TOKEN_KEY = "login_tokens:"; public static final String LOGIN_TOKEN_KEY = "login_tokens:";
/**
* 登录当前在线 用户 redis key
*/
public static final String LOGIN_TOKEN_KEY_ONLINE = "login_tokens_onlie:";
/** /**
* 防重提交 redis key * 防重提交 redis key
*/ */

View File

@ -9,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
@ -23,6 +25,7 @@ public class RedisCache
@Autowired @Autowired
public RedisTemplate redisTemplate; public RedisTemplate redisTemplate;
/** /**
* 缓存基本的对象Integer、String、实体类等 * 缓存基本的对象Integer、String、实体类等
* *
@ -47,6 +50,8 @@ public class RedisCache
redisTemplate.opsForValue().set(key, value, timeout, timeUnit); redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
} }
/** /**
* 设置有效时间 * 设置有效时间
* *
@ -189,6 +194,20 @@ public class RedisCache
redisTemplate.opsForHash().put(key, hKey, value); redisTemplate.opsForHash().put(key, hKey, value);
} }
/**
* 缓存基本的对象Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public boolean delCacheMapKey(final String key,final String... token)
{
return redisTemplate.opsForHash().delete(key,token)>=1;
}
/** /**
* 获取Hash中的数据 * 获取Hash中的数据
* *
@ -224,4 +243,9 @@ public class RedisCache
{ {
return redisTemplate.keys(pattern); return redisTemplate.keys(pattern);
} }
} }