循环遍历获取 redis key实现在用户在线,性能不高,尤其是用户数量多的情况容易导致其他的redis线程卡死.这边用 redis hash维护一个现在用户,只要简单的实现用户同步就可以了.提交了性能
This commit is contained in:
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor
ruoyi-common/src/main/java/com/ruoyi/common
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,12 @@ public class Constants
|
|||||||
* 登录用户 redis key
|
* 登录用户 redis key
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user