ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

权限改了,为什么另一台节点还在放行?

权限改了,为什么另一台节点还在放行? 权限传播的核心不是删掉每一份缓存而是让所有节点认同同一个当前版本。摘要Microi吾码AI 分析当前平台源码后发现多节点权限陈旧问题不能靠缩短 TTL 或重启容器解决。更可靠的边界是权限事实先写入主库随后递增按租户隔离的 Redis 授权版本每个节点先读版本再使用带版本的用户快照Redis 不可用时回源主库不继续相信旧缓存。✦① 这不是浏览器缓存而是授权事实没有换版本管理员刚撤销角色A 节点已经拒绝请求B 节点却仍然放行。最直觉的处理是退出登录、清浏览器缓存、重启 B 节点甚至清空 Redis。它们可能暂时让现象消失却没有回答真正的问题谁负责告诉所有节点上一份授权快照已经失效当前平台把 L1 进程缓存和 Redis L2 都视为性能层而不是权限事实源。每次外部授权判断先读取当前租户的共享版本快照 Key 带上这个版本后旧节点即使还保存着旧对象也无法再通过新 Key 命中它。关键判断真正要跨节点同步的是一个单调递增的授权版本而不是逐台机器追杀所有旧缓存对象。✦② 一次授权判断依次穿过四层版本先行没有拿到可信当前版本时缓存快照不能继续参与授权判断。第一层是 Redis 中按 OsClient 隔离的版本第二层是当前 API 进程的短期 L1第三层是跨节点共享的 Redis L2第四层才是主库冷加载。正常路径追求快但故障路径必须优先正确。L1 只服务当前进程滚动发布或节点重启都可以丢。L2 保存跨节点用户快照但 Key 必须包含当前版本。主库保存用户状态、角色、菜单、操作权限与数据范围的权威事实。无 _SysMenuId 的历史调用也只能从同一快照推断不能绕开行级范围。✦③ Epoch 不删除旧快照只改变它是否还能被到达共享版本最精妙的一点是不要求权限保存时同步扫描并删除所有用户快照。假设版本从 41 增到 42新请求构造的是 v42 的 Keyv41 对象仍可能在 Redis 中等待 TTL 回收但已经不在新请求的可达路径里。versionKey Microi:{OsClient}:FormEngineAuthz:Version snapshotKey Microi:{OsClient}:FormEngineAuthz:Snapshot:v2:{epoch}:{userHash}:{roleSetHash}为什么还带契约版本 v2Redis 会跨进程重启和滚动发布保留数据。快照结构新增安全字段时契约版本必须一起提升避免缺失字段被反序列化成错误默认值。✦④ 权限写入与版本递增的顺序不能颠倒先有新事实再切换所有节点读取的新版本。如果先递增版本、再提交数据库另一个节点可能立刻用新版本冷加载却读到旧事实如果写入成功后忘记递增版本所有节点仍会继续命中旧快照。正确边界是控制面写入完成关联的用户级别、角色、菜单或高级表权限同步完成然后再递增共享版本。var count dbSession.Update(model); if (count 0) { SyncUserLevelsForRole(dbSession, model.Id); await FormEngineAuthorizationCache.InvalidateAsync(osClient); }这里的重点不是这几行代码本身而是提交顺序表达的安全语义新事实必须先存在版本开关才能让其它节点来读取它。✦⑤ Redis 出问题时授权宁可慢也不能旧读取共享版本发生异常时最危险的降级是继续复用进程内最后一份快照。那会把缓存服务故障放大成权限撤销失效。当前实现选择返回空版本让调用方绕过缓存并从主库读取授权可能变慢但不会把旧允许结果当成真。本轮聚焦测试验证 Key 的租户隔离、角色集合顺序稳定与快照契约版本。Redis version read failed → do not use stale snapshot → query primary database → evaluate menu, action, table and row scope✦⑥ 租户、用户与角色集合为什么都要进入 Key授权版本按租户隔离只解决了不同 OsClient 不共享同一轨道快照还要区分用户和有效角色集合。角色顺序不应影响结果因此先去重、归一化并排序后再哈希用户标识也哈希避免把敏感 ID 直接暴露在 Redis Key 中。同角色集合不同顺序生成同一 Key减少无意义重复缓存。不同租户即使版本数字相同Key 也完全不同。用户状态和级别进入快照禁用账号不能只靠前端退出。菜单 SqlWhere、SqlJoin 与 JoinTables 仍要进入最终 SQL不能只缓存允许/拒绝。测试边界本轮 Release 聚焦测试 1/1 通过证明 Key 稳定与租户隔离它不等同于生产 Redis 断网、滚动发布或真实多节点压测。✦⑦ 上线前别再问“缓存多久”先检查这五件事租户隔离、提交后失效、主库回源、契约版本和可观测性共同决定安全边界。版本 Key 是否显式包含 OsClient避免跨租户事实混用。用户、角色、菜单和高级表权限的所有写入口是否都会在成功后递增版本。Redis 异常时是否绕过旧快照并读取主库而不是静默放行。快照结构或解释语义改变时是否提升独立契约版本。日志能否区分版本读取失败、快照读取失败和主库冷加载。TTL 仍然有价值它限制不可达旧对象占用空间但 TTL 不是权限撤销协议。把“清缓存、重启节点”写进日常操作手册只能说明系统尚未建立可靠的版本边界。AI 声明本文社交平台技术概念卡片底图由AI生成并经确定性程序叠加准确中文长文架构图、源码分析与本地测试证据来自当前工作区概念图不冒充运行证据。
返回列表