读完了当前已实现的代码(认证模块)。只基于已经写出来的代码,能用 Redis 的点就下面这些,按收益排序:
- getCurrentUser 整体缓存 —— 现有代码里最大的性能收益点 位置:UserServiceImpl.java:143-154,内部走 loadUserSecurityView(:248-270) 现状:每次调用打 6 条 SQL——selectById(user) + departmentMapper.selectById + getRoleIds(user_role) + getEnabledPermissions(role_permission + permission 两条) + getRoleCodesByRoleIds(role)。前端每次页面初始化/刷新都调,完全无缓存。 Redis 方案:缓存整个 CurrentUserVO → rbac:currentuser:{userId},TTL 30min。 失效:用户/角色/权限变更时 DEL(这些 CRUD 接口目前还没写,先靠 TTL 兜底,等写管理接口时接失效)。
- StpInterfaceImpl 权限/角色缓存 —— 每请求热点 位置:StpInterfaceImpl.java:22-29 → getPermissionCodesByUserId(:240)/getRoleCodesByUserId(:235) 现状:getPermissionList 每次打 3 条 SQL、getRoleList 每次打 2 条,且 getRoleIds 在两边重复查 user_role。每个带 @SaCheckPermission/@SaCheckRole 的请求都会触发。(目前还没加这些注解,所以是休眠状态,一旦加就是头号热点。) Redis 方案:rbac:perms:user:{userId} / rbac:roles:user:{userId},TTL 30min,登录时预热(login() 里 loadUserSecurityView 已经查过同一份数据)。
- loadUserSecurityView 底层字典数据缓存 —— 1 和 2 的共享底座 位置:UserServiceImpl.java:258, 264-266(查 department / user_role / role_permission / permission / role) 现状:permission(~30 条)、role、department 都是几乎不变的字典数据,但 login、current-user、StpInterface 每次都重新查 DB。 Redis 方案:缓存全量 permission 表 rbac:perm:all、role 列表、department 列表,TTL 60min,管理接口变更时 DEL。这样 1/2/login 都能复用。可作为 1、2 的更细粒度替代或补充。
- 验证码 CaptchaCache 迁 Redis —— 多实例正确性 位置:CaptchaCache.java:12(hutool TimedCache,进程内) 现状:多实例下验证码生成和登录校验会落到不同实例 → 校验必失败。 Redis 方案:captcha:{captchaId} TTL 5min,校验时原子 GET+DEL。
- 登录失败锁定 loginFailCache 迁 Redis —— 多实例安全 位置:UserServiceImpl.java:55(hutool TimedCache,进程内 + synchronized) 现状:多实例下失败计数分散在各实例,永远累计不到 5 次,暴力破解防护失效。 Redis 方案:login:fail:{username} 用 INCR 原子累加 TTL 30min,替掉 synchronized 块。 顺带一个非 Redis 的小优化(同代码路径,可顺手做):login():105 和 refreshToken():182 都调了 selectRoleCodeByUserId 查 DB,但 roleCode 登录时已写进 JWT extra(:113),refreshToken 可直接 StpUtil.getExtra(“roleCode”) 读取省一次 DB;login 里这查询也和 loadUserSecurityView 的 getRoleIds+getRoleCodesByRoleIds 重复,可复用。
就这 5 个(+1 个非 Redis)。1/2/3 是性能收益,4/5 是多实例正确性/安全。