杭州市网站建设_网站建设公司_VPS_seo优化
2026/1/10 23:02:35 网站建设 项目流程

——从“清缓存”到“权限版本化”的必然演进

在中小系统中,Shiro 的权限更新通常靠一句话解决:

“角色权限改了,把缓存清一下就好了。”

但当系统规模上升到几十万、百万用户时,这种做法会迅速失效,甚至直接成为系统稳定性的隐患

本文将系统梳理:
在百万用户规模下,Shiro 权限更新到底应该怎么设计,才能长期可控。


一、问题的本质:Shiro 权限为什么“改了不生效”

1. Shiro 的授权机制是“一次加载,多次复用”

Shiro 的授权流程本质上是:

  1. 首次进行权限校验

  2. 调用doGetAuthorizationInfo

  3. 返回角色与功能权限

  4. 结果进入缓存

  5. 后续不再访问数据库

因此:

  • 数据库权限更新 ✅

  • Shiro 授权缓存仍是旧值 ❌

  • 权限自然不会生效

这不是 Bug,而是 Shiro 的设计前提。


2. 小系统能“清缓存”,大系统不行

在用户量较小的时候,常见做法是:

  • 清指定用户缓存

  • 或直接clearAllCachedAuthorizationInfo

这些做法在百万用户系统中全部不可用


二、为什么“按用户清权限缓存”在百万用户下必炸

1. 数量级问题,而不是代码问题

假设:

  • 一个角色下 10 万用户

  • 系统 10 个实例

  • 使用 Redis 或本地缓存

你需要:

  • 找出 10 万个 userId

  • 在多个实例上逐一清缓存

  • 还要保证一致性

这是O(N)行为,在百万用户系统中是架构级错误


2. 全量清缓存是“权限雪崩”

clearAllCachedAuthorizationInfo()的真实后果是:

  • 所有在线用户权限瞬间失效

  • 同一时间触发大量权限重算

  • 数据库、权限服务瞬时承压

在大系统中,这是事故级操作


三、核心转变:从“刷新用户权限”到“权限版本化”

架构级结论(非常重要)

在百万用户系统中,
权限更新不再是“操作用户”,
而是“声明规则已变更”。

这意味着:

  • 不关心“谁在线”

  • 不关心“哪些用户受影响”

  • 只关心:当前权限规则版本


四、权限版本号模型(唯一可扩展方案)

1. 权限版本的基本建模

至少需要两级版本号:

Tenant Permission Version Role Permission Version

示例:

tenant(id, perm_version) role(id, perm_version)

规则非常简单:

只要权限发生变化,版本号 +1


2. 角色权限更新时做什么

百万用户系统中,你只做这一件事

UPDATE role SET perm_version = perm_version + 1 WHERE id = :roleId;

  • O(1) 操作

  • 不依赖用户数量

  • 全量生效


五、Shiro 在版本化权限中的正确职责

1. Shiro 仍然只负责“功能权限”

Shiro 中只管理:

  • 角色

  • 功能权限(菜单、按钮、接口)

数据权限、字段权限必须完全独立。


2. 登录时:记录“权限版本快照”

登录成功后,Shiro 的 Principal 中只保存:

class LoginPrincipal { Long userId; Long roleId; Long rolePermVersionSnapshot; }

注意:

  • 不保存权限明细

  • 不保存数据范围


六、权限校验时的真实流程(关键)

当 Shiro 触发权限校验时:

触发授权 ↓ 读取当前角色 perm_version ↓ 与 Principal 中的 snapshot 对比 ↓ 不一致? ↓ 重新加载 AuthorizationInfo ↓ 更新 snapshot

这个过程是:

  • 惰性触发

  • 按需重算

  • 对用户无感知


七、缓存策略的根本变化

1. 小系统的缓存方式(错误示例)

userId → AuthorizationInfo

在百万用户系统中,这是不可扩展的。


2. 正确的缓存方式

(roleId + perm_version) → AuthorizationInfo

含义是:

权限的缓存对象是“角色规则”,而不是“用户状态”

这也是版本化模型的核心价值。


八、事件驱动在百万用户系统中的真实作用

重要认知修正

事件驱动不是“必须”,而是“加速器”。

正确用法

  • 权限更新 → version +1(必做)

  • 同时发布事件(可选)

  • 各节点清理角色级缓存

即使事件丢失:

  • 版本号依然兜底

  • 权限不会错乱


九、Shiro 在百万用户系统中的边界

必须明确以下事实:

能力是否适合 Shiro
功能权限
菜单 / 按钮
数据行权限
字段级权限
动态权限规则

Shiro 是“授权入口”,不是“权限引擎”。


十、最终可执行结论(团队级)

百万用户系统中的 Shiro 权限更新原则

  1. 禁止用户级权限刷新

  2. 权限更新 = 版本号递增

  3. 权限生效 = 惰性重算

  4. 缓存以“角色 + 版本”为维度

  5. 事件驱动只做加速,不做依赖


一句话总结

当用户规模进入百万级,
“清缓存”不再是技术问题,而是架构错误。

权限系统必须从“面向用户操作”,
转变为“面向规则演进”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询