From 317f1cd02f0627a9b31df7a6f4e05173944f6976 Mon Sep 17 00:00:00 2001 From: lzh Date: Thu, 23 Apr 2026 16:10:41 +0800 Subject: [PATCH] =?UTF-8?q?perf(system):=20isSuperAdmin=20=E5=88=87?= =?UTF-8?q?=E5=88=B0=20getUserRoleIdListByUserIdFromCache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复 /admin-api/system/auth/get-permission-info 等接口大面积超时: 原因:ProjectSecurityWebFilter 每次 admin-api 请求都调一次 ProjectService.getAuthorizedProjectIds(userId),我之前在里面塞的 isSuperAdmin 用了无缓存的 getUserRoleIdListByUserId, 每请求一次 SELECT system_user_role,并发下直接打爆 DB。 切到 getUserRoleIdListByUserIdFromCache(@Cacheable 走 Redis USER_ROLE_ID_LIST),首次查 DB、后续命中缓存,该缓存在 assignUserRole / processUserDeleted / updateUserRole 等写入点 都已正确 CacheEvict。 同时修正 UserProjectServiceImpl.isSuperAdmin 同样问题。 Co-Authored-By: Claude Opus 4.7 (1M context) --- .../module/system/service/project/ProjectServiceImpl.java | 7 +++++-- .../system/service/project/UserProjectServiceImpl.java | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/service/project/ProjectServiceImpl.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/service/project/ProjectServiceImpl.java index 2da0a696..d84d12eb 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/service/project/ProjectServiceImpl.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/service/project/ProjectServiceImpl.java @@ -170,13 +170,16 @@ public class ProjectServiceImpl implements ProjectService { /** * 判断用户是否为超级管理员 - * 查角色列表 → hasAnySuperAdmin 判别 + * + * 注意:必须使用 FromCache 版本,本方法被 ProjectSecurityWebFilter 每次请求都会调用, + * 走无缓存的 getUserRoleIdListByUserId 会直接把 system_user_role 打爆, + * 典型症状是 /admin-api/** 接口(如 get-permission-info)大面积超时。 */ private boolean isSuperAdmin(Long userId) { if (userId == null) { return false; } - Set roleIds = permissionService.getUserRoleIdListByUserId(userId); + Set roleIds = permissionService.getUserRoleIdListByUserIdFromCache(userId); if (CollUtil.isEmpty(roleIds)) { return false; } diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/service/project/UserProjectServiceImpl.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/service/project/UserProjectServiceImpl.java index e6b5017f..c7babd40 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/service/project/UserProjectServiceImpl.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/service/project/UserProjectServiceImpl.java @@ -258,12 +258,15 @@ public class UserProjectServiceImpl implements UserProjectService { /** * 判断用户是否超管 + * + * 必须走 FromCache 版本,否则调用点(removeProjectUser / getProjectUserPage) + * 在高并发场景(比如批量移除成员)下会放大 DB 压力。 */ private boolean isSuperAdmin(Long userId) { if (userId == null) { return false; } - Set roleIds = permissionService.getUserRoleIdListByUserId(userId); + Set roleIds = permissionService.getUserRoleIdListByUserIdFromCache(userId); if (CollUtil.isEmpty(roleIds)) { return false; }