|
|
|
|
# 缓存架构设计
|
|
|
|
|
|
|
|
|
|
<cite>
|
|
|
|
|
**本文引用的文件**
|
|
|
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
- [application.yml(应用配置)](file://crm-app/src/main/resources/application.yml)
|
|
|
|
|
- [application.yml(认证模块配置)](file://crm-auth/src/main/resources/application.yml)
|
|
|
|
|
</cite>
|
|
|
|
|
|
|
|
|
|
## 目录
|
|
|
|
|
1. [引言](#引言)
|
|
|
|
|
2. [项目结构](#项目结构)
|
|
|
|
|
3. [核心组件](#核心组件)
|
|
|
|
|
4. [架构总览](#架构总览)
|
|
|
|
|
5. [详细组件分析](#详细组件分析)
|
|
|
|
|
6. [依赖关系分析](#依赖关系分析)
|
|
|
|
|
7. [性能考量与调优](#性能考量与调优)
|
|
|
|
|
8. [故障排查指南](#故障排查指南)
|
|
|
|
|
9. [结论](#结论)
|
|
|
|
|
10. [附录](#附录)
|
|
|
|
|
|
|
|
|
|
## 引言
|
|
|
|
|
本文件面向CRM系统的缓存架构设计与优化,聚焦以下目标:
|
|
|
|
|
- 基于Redis的缓存策略与分布式会话管理
|
|
|
|
|
- 部门树缓存的实现与更新机制
|
|
|
|
|
- Redis连接池、序列化策略与过期时间管理
|
|
|
|
|
- 令牌存储方案与一致性保障
|
|
|
|
|
- 缓存穿透防护、热点数据优化与监控指标
|
|
|
|
|
- 为性能优化工程师与系统管理员提供调优与排障指南
|
|
|
|
|
|
|
|
|
|
## 项目结构
|
|
|
|
|
本项目采用多模块组织,缓存相关能力主要分布在基础模块与认证模块:
|
|
|
|
|
- crm-base:通用基础设施,包含Redis配置、工具类、异常处理等
|
|
|
|
|
- crm-auth:认证与权限域,包含令牌服务、部门树缓存、安全过滤器等
|
|
|
|
|
- crm-app:应用入口与全局配置
|
|
|
|
|
- crm-file:文件服务(与缓存主题关联度较低)
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
graph TB
|
|
|
|
|
subgraph "应用层"
|
|
|
|
|
APP["crm-app<br/>应用启动与全局配置"]
|
|
|
|
|
end
|
|
|
|
|
subgraph "业务域"
|
|
|
|
|
AUTH["crm-auth<br/>认证与权限<br/>TokenService / DeptTreeCache"]
|
|
|
|
|
FILE["crm-file<br/>文件服务"]
|
|
|
|
|
end
|
|
|
|
|
subgraph "基础能力"
|
|
|
|
|
BASE["crm-base<br/>RedisConfig / 工具 / 异常"]
|
|
|
|
|
end
|
|
|
|
|
subgraph "外部依赖"
|
|
|
|
|
REDIS["Redis 集群/单机"]
|
|
|
|
|
end
|
|
|
|
|
APP --> AUTH
|
|
|
|
|
APP --> FILE
|
|
|
|
|
AUTH --> BASE
|
|
|
|
|
FILE --> BASE
|
|
|
|
|
AUTH --> REDIS
|
|
|
|
|
FILE --> REDIS
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
图表来源
|
|
|
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [application.yml(应用配置)](file://crm-app/src/main/resources/application.yml)
|
|
|
|
|
- [application.yml(认证模块配置)](file://crm-auth/src/main/resources/application.yml)
|
|
|
|
|
|
|
|
|
|
## 核心组件
|
|
|
|
|
- RedisConfig:统一配置Redis连接池、序列化器、Key/Value序列化策略、默认过期时间、是否启用缓存开关等
|
|
|
|
|
- DeptTreeCache:部门树结构的缓存封装,提供读取、构建、刷新、失效等操作
|
|
|
|
|
- TokenService:用户登录态与令牌生命周期管理,结合Redis实现分布式会话与令牌存储
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
|
|
|
|
|
## 架构总览
|
|
|
|
|
整体缓存架构围绕“统一配置 + 领域缓存 + 令牌服务”展开,所有读写均通过Redis客户端访问。
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
graph TB
|
|
|
|
|
Client["客户端/网关"] --> API["API 控制器"]
|
|
|
|
|
API --> AuthSvc["认证服务/权限校验"]
|
|
|
|
|
AuthSvc --> TokenSrv["TokenService<br/>令牌存取/续期/注销"]
|
|
|
|
|
AuthSvc --> DeptCache["DeptTreeCache<br/>部门树缓存"]
|
|
|
|
|
TokenSrv --> Redis["Redis"]
|
|
|
|
|
DeptCache --> Redis
|
|
|
|
|
API --> BaseCfg["RedisConfig<br/>连接池/序列化/TTL"]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
图表来源
|
|
|
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
feat(auth): role management — ancestor completion, CRUD, permission assignment, cascade delete (ADR-0012)
Implements ADR-0005 (backend ancestor completion) and ADR-0012 (role management
architecture) across 5 tracer-bullet tickets:
- ISysMenuService.getAncestorIds: batch query full table, in-memory parentId
traversal, returns complete ancestor set (ADR-0005)
- SysRole.builtin field + DataInitializer idempotent refactor + 5 button
permission seeds (crm:role:list/detail/save/delete/assign) bound to ADMIN
- RoleController (/api/roles/*): page, saveOrUpdate, detail, assign-resources,
delete — pure hasAuthority, POST + action suffix, form params
- SysRoleServiceImpl.saveRole: roleCode uniqueness, builtin protection,
dataScope 1-4 range, create can't set builtin=true
- assignResources: calls getAncestorIds for ancestor completion, then
full replacement (delete + insert) of sys_role_menu
- getRoleDetail: returns RoleDetailVO with basic info + resourceIds
- deleteRoleCascade: cleans sys_role_menu + sys_user_role, builtin rejection,
three-table transaction
- SystemController: all role endpoints removed, unused deps cleaned
- Dead code removed: assignMenus, getMenuIdsByRoleId (superseded by
assignResources, getRoleDetail)
- H2 test schemas updated with builtin column
- 150 tests pass (16 new in SysRoleServiceImplTest, 7 in SysMenuServiceImplTest)
1 month ago
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
|
|
|
|
|
## 详细组件分析
|
|
|
|
|
|
|
|
|
|
### RedisConfig:连接池、序列化与过期时间
|
|
|
|
|
职责与要点
|
|
|
|
|
- 连接池参数:最大连接数、最小空闲、最大等待时间、超时等,影响吞吐与延迟
|
|
|
|
|
- 序列化策略:Key/Value序列化器选择,避免跨语言或版本兼容问题
|
|
|
|
|
- 默认过期时间:为无明确TTL的键设置保护性过期,降低内存泄漏风险
|
|
|
|
|
- 缓存开关:便于灰度与回滚控制
|
|
|
|
|
|
|
|
|
|
关键配置项建议
|
|
|
|
|
- 连接池:根据实例规格与QPS预估调整maxTotal/maxIdle/minIdle
|
|
|
|
|
- 序列化:优先使用JSON或Kryo;Key需短小稳定,避免大对象
|
|
|
|
|
- TTL:按业务场景设定合理过期时间,热点数据可配合逻辑过期
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
|
|
|
|
- [application.yml(应用配置)](file://crm-app/src/main/resources/application.yml)
|
|
|
|
|
- [application.yml(认证模块配置)](file://crm-auth/src/main/resources/application.yml)
|
|
|
|
|
|
|
|
|
|
### DeptTreeCache:部门树缓存与更新机制
|
|
|
|
|
职责与要点
|
|
|
|
|
- 读路径:优先从Redis获取部门树,未命中则回源数据库并回填缓存
|
|
|
|
|
- 写路径:部门变更时主动失效对应缓存,保证后续读取一致性
|
|
|
|
|
- 防抖与锁:并发重建时加分布式锁,避免缓存击穿
|
|
|
|
|
- 数据结构:以扁平化节点+层级信息或压缩后的树结构存储
|
|
|
|
|
|
|
|
|
|
更新流程图
|
|
|
|
|
```mermaid
|
|
|
|
|
flowchart TD
|
|
|
|
|
Start(["请求进入"]) --> CheckCache["检查Redis中是否存在部门树"]
|
|
|
|
|
CheckCache --> |存在| ReturnCache["返回缓存结果"]
|
|
|
|
|
CheckCache --> |不存在| TryLock{"尝试获取分布式锁"}
|
|
|
|
|
TryLock --> |失败| Fallback["降级:直接查库或返回空/旧值"]
|
|
|
|
|
TryLock --> |成功| BuildTree["构建部门树"]
|
|
|
|
|
BuildTree --> SaveCache["写入Redis并设置TTL"]
|
|
|
|
|
SaveCache --> ReleaseLock["释放锁"]
|
|
|
|
|
ReleaseLock --> ReturnCache
|
|
|
|
|
Fallback --> End(["结束"])
|
|
|
|
|
ReturnCache --> End
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
图表来源
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
|
|
|
|
|
### TokenService:令牌存储与分布式会话
|
|
|
|
|
职责与要点
|
|
|
|
|
- 令牌生成:唯一ID、签发时间、过期时间、用户标识、设备信息等
|
|
|
|
|
- 存储结构:以Hash或String形式存储用户会话,支持快速查询与续期
|
|
|
|
|
- 过期策略:滑动过期或固定过期,结合定时任务清理过期会话
|
|
|
|
|
- 注销与黑名单:登出时删除或加入黑名单,防止重放攻击
|
|
|
|
|
|
|
|
|
|
序列图(登录到鉴权)
|
|
|
|
|
```mermaid
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
participant C as "客户端"
|
|
|
|
|
participant A as "认证控制器"
|
|
|
|
|
participant T as "TokenService"
|
|
|
|
|
participant R as "Redis"
|
|
|
|
|
C->>A : "提交用户名/密码"
|
|
|
|
|
A->>T : "验证并签发令牌"
|
|
|
|
|
T->>R : "存储会话(含TTL)"
|
|
|
|
|
R-->>T : "写入成功"
|
|
|
|
|
T-->>A : "返回令牌"
|
|
|
|
|
A-->>C : "响应令牌"
|
|
|
|
|
Note over C,R : "后续请求携带令牌,服务端校验并续期"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
图表来源
|
|
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
|
|
|
|
|
## 依赖关系分析
|
|
|
|
|
- RedisConfig被各模块共享,作为统一的Redis接入点
|
|
|
|
|
- DeptTreeCache依赖Redis进行部门树的读写
|
|
|
|
|
- TokenService依赖Redis进行会话与令牌管理
|
|
|
|
|
- 认证流程同时依赖两者,形成“令牌 + 数据缓存”的双通道
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
classDiagram
|
|
|
|
|
class RedisConfig {
|
|
|
|
|
+连接池配置
|
|
|
|
|
+序列化器配置
|
|
|
|
|
+默认TTL
|
|
|
|
|
+缓存开关
|
|
|
|
|
}
|
|
|
|
|
class DeptTreeCache {
|
|
|
|
|
+getTree()
|
|
|
|
|
+refreshTree()
|
|
|
|
|
+invalidate()
|
|
|
|
|
}
|
|
|
|
|
class TokenService {
|
|
|
|
|
+createToken(user)
|
|
|
|
|
+validateToken(token)
|
|
|
|
|
+refreshToken(token)
|
|
|
|
|
+logout(token)
|
|
|
|
|
}
|
|
|
|
|
DeptTreeCache --> RedisConfig : "使用"
|
|
|
|
|
TokenService --> RedisConfig : "使用"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
图表来源
|
|
|
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
|
|
|
|
|
## 性能考量与调优
|
|
|
|
|
- 连接池调优
|
|
|
|
|
- maxTotal:根据CPU核数与网络带宽估算,通常不超过线程池上限
|
|
|
|
|
- minIdle:保持一定空闲连接,减少冷启动抖动
|
|
|
|
|
- maxWaitMillis:避免排队过长导致超时
|
|
|
|
|
- 序列化优化
|
|
|
|
|
- Key尽量短且稳定,避免拼接过长字符串
|
|
|
|
|
- Value避免大对象,必要时分片或压缩
|
|
|
|
|
- 选择合适的序列化器,权衡CPU与体积
|
|
|
|
|
- TTL与过期
|
|
|
|
|
- 热点数据设置较长TTL,配合逻辑过期与后台刷新
|
|
|
|
|
- 非热点数据设置较短TTL,降低内存占用
|
|
|
|
|
- 热点数据优化
|
|
|
|
|
- 本地缓存(如Caffeine)+ 二级缓存(Redis)
|
|
|
|
|
- 预加载与预热,避免突发流量击穿
|
|
|
|
|
- 监控指标
|
|
|
|
|
- 命中率、平均延迟、P99/P999延迟、错误率
|
|
|
|
|
- Redis连接池使用率、活跃连接数、阻塞队列长度
|
|
|
|
|
- 内存使用量、碎片率、慢查询数量
|
|
|
|
|
|
|
|
|
|
[本节为通用指导,不直接分析具体文件]
|
|
|
|
|
|
|
|
|
|
## 故障排查指南
|
|
|
|
|
常见问题与定位步骤
|
|
|
|
|
- 连接池耗尽
|
|
|
|
|
- 现象:大量超时、连接拒绝
|
|
|
|
|
- 排查:查看连接池指标、慢查询、长事务
|
|
|
|
|
- 处置:扩容连接池、缩短请求耗时、增加重试退避
|
|
|
|
|
- 序列化异常
|
|
|
|
|
- 现象:反序列化失败、类型不匹配
|
|
|
|
|
- 排查:检查Key/Value格式、版本兼容性
|
|
|
|
|
- 处置:统一序列化器、迁移历史数据
|
|
|
|
|
- 缓存不一致
|
|
|
|
|
- 现象:读不到最新数据、脏读
|
|
|
|
|
- 排查:确认写后失效策略、分布式锁是否生效
|
|
|
|
|
- 处置:加强失效粒度、引入版本号或双写校验
|
|
|
|
|
- 令牌失效异常
|
|
|
|
|
- 现象:频繁登出、会话丢失
|
|
|
|
|
- 排查:检查TTL、续期逻辑、时钟同步
|
|
|
|
|
- 处置:修正TTL、完善续期策略、对齐服务器时间
|
|
|
|
|
|
|
|
|
|
章节来源
|
|
|
|
|
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
|
|
|
|
|
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
|
|
|
|
|
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
|
|
|
|
|
|
|
|
|
|
## 结论
|
|
|
|
|
本缓存架构以Redis为核心,通过统一配置、领域缓存与令牌服务协同工作,满足高并发与一致性的基本要求。建议在上线前完成容量规划与压测,建立完善的监控告警体系,并在变更时遵循“先扩后缩、灰度发布”的原则,确保稳定性与可观测性。
|
|
|
|
|
|
|
|
|
|
[本节为总结性内容,不直接分析具体文件]
|
|
|
|
|
|
|
|
|
|
## 附录
|
|
|
|
|
- 术语说明
|
|
|
|
|
- TTL:生存时间(Time To Live)
|
|
|
|
|
- P99/P999:延迟分布的分位指标
|
|
|
|
|
- 击穿/穿透/雪崩:缓存常见异常模式
|
|
|
|
|
- 参考实践
|
|
|
|
|
- 热点数据多级缓存
|
|
|
|
|
- 分布式锁与防抖
|
|
|
|
|
- 令牌滑动续期与黑名单
|
|
|
|
|
|
|
|
|
|
[本节为补充信息,不直接分析具体文件]
|