From df5edb67f02935da3e231dda3364e7463b2adde2 Mon Sep 17 00:00:00 2001 From: 疯狂的狮子Li <15040126243@163.com> Date: 星期二, 02 一月 2024 20:01:09 +0800 Subject: [PATCH] [重大更新] 使用caffeine重构PlusSaTokenDao层实现 减少将近90%的redis查询提高性能(尝试性更新问题未知 请勿轻易更新尝试) --- ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java | 22 +++---- ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java | 17 ++--- ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java | 1 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java | 35 ++++++++++- ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java | 53 ++++++----------- ruoyi-common/ruoyi-common-satoken/pom.xml | 5 + 6 files changed, 73 insertions(+), 60 deletions(-) diff --git a/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java b/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java index 6d67fb1..b3afea4 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java @@ -10,7 +10,6 @@ import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.constant.Constants; import org.dromara.common.core.domain.dto.UserOnlineDTO; -import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.utils.MessageUtils; import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.SpringUtils; @@ -43,7 +42,6 @@ public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) { UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); String ip = ServletUtils.getClientIP(); - LoginUser user = LoginHelper.getLoginUser(); UserOnlineDTO dto = new UserOnlineDTO(); dto.setIpaddr(ip); dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); @@ -51,10 +49,11 @@ dto.setOs(userAgent.getOs().getName()); dto.setLoginTime(System.currentTimeMillis()); dto.setTokenId(tokenValue); - dto.setUserName(user.getUsername()); - dto.setClientKey(user.getClientKey()); - dto.setDeviceType(user.getDeviceType()); - dto.setDeptName(user.getDeptName()); + String username = (String) loginModel.getExtra(LoginHelper.USER_NAME_KEY); + dto.setUserName(username); + dto.setClientKey((String) loginModel.getExtra(LoginHelper.CLIENT_KEY)); + dto.setDeviceType(loginModel.getDevice()); + dto.setDeptName((String) loginModel.getExtra(LoginHelper.DEPT_NAME_KEY)); if(tokenConfig.getTimeout() == -1) { RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); } else { @@ -62,14 +61,14 @@ } // 璁板綍鐧诲綍鏃ュ織 LogininforEvent logininforEvent = new LogininforEvent(); - logininforEvent.setTenantId(user.getTenantId()); - logininforEvent.setUsername(user.getUsername()); + logininforEvent.setTenantId((String) loginModel.getExtra(LoginHelper.TENANT_KEY)); + logininforEvent.setUsername(username); logininforEvent.setStatus(Constants.LOGIN_SUCCESS); logininforEvent.setMessage(MessageUtils.message("user.login.success")); logininforEvent.setRequest(ServletUtils.getRequest()); SpringUtils.context().publishEvent(logininforEvent); // 鏇存柊鐧诲綍淇℃伅 - loginService.recordLoginInfo(user.getUserId(), ip); + loginService.recordLoginInfo((Long) loginModel.getExtra(LoginHelper.USER_KEY), ip); log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); } diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java index a7bca20..7f6ab1f 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java @@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.dromara.common.core.context.ThreadLocalHolder; import java.util.HashMap; import java.util.Map; diff --git a/ruoyi-common/ruoyi-common-satoken/pom.xml b/ruoyi-common/ruoyi-common-satoken/pom.xml index 01c282b..4df7d4d 100644 --- a/ruoyi-common/ruoyi-common-satoken/pom.xml +++ b/ruoyi-common/ruoyi-common-satoken/pom.xml @@ -36,6 +36,11 @@ <artifactId>sa-token-jwt</artifactId> </dependency> + <dependency> + <groupId>com.github.ben-manes.caffeine</groupId> + <artifactId>caffeine</artifactId> + </dependency> + </dependencies> </project> diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java index d885962..b262d07 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java @@ -2,12 +2,16 @@ import cn.dev33.satoken.dao.SaTokenDao; import cn.dev33.satoken.util.SaFoxUtil; +import cn.hutool.core.lang.Console; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import org.dromara.common.redis.utils.RedisUtils; import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.concurrent.TimeUnit; /** * Sa-Token鎸佷箙灞傛帴鍙�(浣跨敤妗嗘灦鑷甫RedisUtils瀹炵幇 鍗忚缁熶竴) @@ -16,12 +20,23 @@ */ public class PlusSaTokenDao implements SaTokenDao { + private static final Cache<String, Object> CAFFEINE = Caffeine.newBuilder() + // 璁剧疆鏈�鍚庝竴娆″啓鍏ユ垨璁块棶鍚庣粡杩囧浐瀹氭椂闂磋繃鏈� + .expireAfterWrite(10, TimeUnit.SECONDS) + // 鍒濆鐨勭紦瀛樼┖闂村ぇ灏� + .initialCapacity(100) + // 缂撳瓨鐨勬渶澶ф潯鏁� + .maximumSize(1000) + .build(); + /** * 鑾峰彇Value锛屽鏃犺繑绌� */ @Override public String get(String key) { - return RedisUtils.getCacheObject(key); + Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key)); + Console.log("caffeine -> key:" + key + ",value:" + o); + return (String) o; } /** @@ -38,6 +53,7 @@ } else { RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout)); } + CAFFEINE.put(key, value); } /** @@ -47,6 +63,7 @@ public void update(String key, String value) { if (RedisUtils.hasKey(key)) { RedisUtils.setCacheObject(key, value, true); + CAFFEINE.put(key, value); } } @@ -81,7 +98,9 @@ */ @Override public Object getObject(String key) { - return RedisUtils.getCacheObject(key); + Object o = CAFFEINE.get(key, k -> RedisUtils.getCacheObject(key)); + Console.log("caffeine -> key:" + key + ",value:" + o); + return o; } /** @@ -98,6 +117,7 @@ } else { RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout)); } + CAFFEINE.put(key, object); } /** @@ -107,6 +127,7 @@ public void updateObject(String key, Object object) { if (RedisUtils.hasKey(key)) { RedisUtils.setCacheObject(key, object, true); + CAFFEINE.put(key, object); } } @@ -139,10 +160,14 @@ /** * 鎼滅储鏁版嵁 */ + @SuppressWarnings("unchecked") @Override public List<String> searchData(String prefix, String keyword, int start, int size, boolean sortType) { - Collection<String> keys = RedisUtils.keys(prefix + "*" + keyword + "*"); - List<String> list = new ArrayList<>(keys); - return SaFoxUtil.searchList(list, start, size, sortType); + String keyStr = prefix + "*" + keyword + "*"; + return (List<String>) CAFFEINE.get(keyStr, k -> { + Collection<String> keys = RedisUtils.keys(keyStr); + List<String> list = new ArrayList<>(keys); + return SaFoxUtil.searchList(list, start, size, sortType); + }); } } diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java index ace6c07..db80f08 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java @@ -9,12 +9,10 @@ import lombok.NoArgsConstructor; import org.dromara.common.core.constant.TenantConstants; import org.dromara.common.core.constant.UserConstants; -import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.enums.UserType; import java.util.Set; -import java.util.function.Supplier; /** * 鐧诲綍閴存潈鍔╂墜 @@ -34,9 +32,10 @@ public static final String LOGIN_USER_KEY = "loginUser"; public static final String TENANT_KEY = "tenantId"; public static final String USER_KEY = "userId"; + public static final String USER_NAME_KEY = "userName"; public static final String DEPT_KEY = "deptId"; + public static final String DEPT_NAME_KEY = "deptName"; public static final String CLIENT_KEY = "clientid"; - public static final String TENANT_ADMIN_KEY = "isTenantAdmin"; /** * 鐧诲綍绯荤粺 鍩轰簬 璁惧绫诲瀷 @@ -46,15 +45,15 @@ * @param model 閰嶇疆鍙傛暟 */ public static void login(LoginUser loginUser, SaLoginModel model) { - ThreadLocalHolder.set(LOGIN_USER_KEY, loginUser); - ThreadLocalHolder.set(TENANT_KEY, loginUser.getTenantId()); - ThreadLocalHolder.set(USER_KEY, loginUser.getUserId()); - ThreadLocalHolder.set(DEPT_KEY, loginUser.getDeptId()); model = ObjectUtil.defaultIfNull(model, new SaLoginModel()); StpUtil.login(loginUser.getLoginId(), model.setExtra(TENANT_KEY, loginUser.getTenantId()) .setExtra(USER_KEY, loginUser.getUserId()) - .setExtra(DEPT_KEY, loginUser.getDeptId())); + .setExtra(DEPT_KEY, loginUser.getDeptId()) + .setExtra(TENANT_KEY, loginUser.getTenantId()) + .setExtra(DEPT_NAME_KEY, loginUser.getDeptName()) + .setExtra(USER_NAME_KEY, loginUser.getUsername()) + ); SaSession tokenSession = StpUtil.getTokenSession(); tokenSession.updateTimeout(model.getTimeout()); tokenSession.set(LOGIN_USER_KEY, loginUser); @@ -64,13 +63,11 @@ * 鑾峰彇鐢ㄦ埛(澶氱骇缂撳瓨) */ public static LoginUser getLoginUser() { - return (LoginUser) getStorageIfAbsentSet(LOGIN_USER_KEY, () -> { - SaSession session = StpUtil.getTokenSession(); - if (ObjectUtil.isNull(session)) { - return null; - } - return session.get(LOGIN_USER_KEY); - }); + SaSession session = StpUtil.getTokenSession(); + if (ObjectUtil.isNull(session)) { + return null; + } + return (LoginUser) session.get(LOGIN_USER_KEY); } /** @@ -88,7 +85,7 @@ * 鑾峰彇鐢ㄦ埛id */ public static Long getUserId() { - return Convert.toLong(getExtra(USER_KEY)); + return Convert.toLong(getExtra(USER_KEY)); } /** @@ -106,7 +103,12 @@ } private static Object getExtra(String key) { - return getStorageIfAbsentSet(key, () -> StpUtil.getExtra(key)); + try { + return StpUtil.getExtra(key); + } catch (Exception e) { + return null; + } + } /** @@ -149,26 +151,11 @@ } public static boolean isTenantAdmin() { - Object value = getStorageIfAbsentSet(TENANT_ADMIN_KEY, () -> { - return isTenantAdmin(getLoginUser().getRolePermission()); - }); - return Convert.toBool(value); + return Convert.toBool(isTenantAdmin(getLoginUser().getRolePermission())); } public static boolean isLogin() { return getLoginUser() != null; } - public static Object getStorageIfAbsentSet(String key, Supplier<Object> handle) { - try { - Object obj = ThreadLocalHolder.get(key); - if (ObjectUtil.isNull(obj)) { - obj = handle.get(); - ThreadLocalHolder.set(key, obj); - } - return obj; - } catch (Exception e) { - return null; - } - } } diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java index ace0668..211cefa 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java @@ -4,17 +4,14 @@ import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpUtil; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.security.config.properties.SecurityProperties; import org.dromara.common.security.handler.AllUrlHandler; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; @@ -63,7 +60,7 @@ } // 淇濆瓨鐢ㄦ埛淇℃伅 - ThreadLocalHolder.set(LoginHelper.LOGIN_USER_KEY, LoginHelper.getLoginUser()); +// ThreadLocalHolder.set(LoginHelper.LOGIN_USER_KEY, LoginHelper.getLoginUser()); // 鏈夋晥鐜囧奖鍝� 鐢ㄤ簬涓存椂娴嬭瘯 // if (log.isDebugEnabled()) { @@ -73,12 +70,13 @@ }); }) - { - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - ThreadLocalHolder.remove(LoginHelper.LOGIN_USER_KEY); - } - }).addPathPatterns("/**") +// { +// @Override +// public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { +// ThreadLocalHolder.clear(); +// } +// } + ).addPathPatterns("/**") // 鎺掗櫎涓嶉渶瑕佹嫤鎴殑璺緞 .excludePathPatterns(securityProperties.getExcludes()); } -- Gitblit v1.9.3