# 缓存配置 **本文引用的文件** - [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.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) ## 更新摘要 **所做更改** - 更新了 Redis 连接配置部分,反映密码认证已启用的变更 - 在故障排查指南中增加了密码认证相关的排查内容 - 更新了安全配置建议,强调生产环境密码管理最佳实践 ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件围绕项目的缓存配置与使用进行系统化说明,重点覆盖: - Redis 连接与序列化配置要点(包含密码认证配置) - 缓存注解的使用方式(如 @Cacheable/@CacheEvict) - 自定义缓存组件实现(以部门树缓存为例) - 缓存键设计策略、失效机制与穿透防护 - 性能优化建议、集群模式配置、监控与调试方法 ## 项目结构 本项目采用多模块组织,缓存相关能力集中在基础模块的 Redis 配置中,业务模块通过服务层与自定义缓存组件进行使用。关键路径如下: - 基础配置:RedisConfig.java - 应用配置:crm-app/application.yml, crm-auth/application.yml - 业务缓存:DeptTreeCache.java - 业务服务:SysDeptServiceImpl.java - 数据访问:SysDeptMapper.java ```mermaid graph TB subgraph "基础模块" A["RedisConfig.java"] end subgraph "应用模块" B["crm-app/application.yml"] C["crm-auth/application.yml"] end subgraph "认证模块" D["DeptTreeCache.java"] E["SysDeptServiceImpl.java"] F["SysDeptMapper.java"] end B --> A C --> A E --> D D --> A E --> F ``` 图表来源 - [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.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) 章节来源 - [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) ## 核心组件 - Redis 配置类:负责连接工厂、序列化器、模板装配等 - 应用配置文件:集中管理 Redis 连接参数、超时、序列化等(包含密码认证) - 部门树缓存组件:封装部门树的读取、写入、失效与键生成逻辑 - 部门服务实现:在查询与更新时调用缓存组件,保证一致性 章节来源 - [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.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) ## 架构总览 下图展示了从请求进入服务层到缓存命中/回源再到数据库的完整流程,以及缓存失效时的更新路径。 ```mermaid sequenceDiagram participant Client as "客户端" participant Service as "SysDeptServiceImpl" participant Cache as "DeptTreeCache" participant Redis as "Redis(由RedisTemplate操作)" participant DB as "数据库(SysDeptMapper)" Client->>Service : "获取部门树" Service->>Cache : "getDeptTree()" alt "缓存命中" Cache-->>Service : "返回树结构" Service-->>Client : "返回结果" else "缓存未命中" Cache->>DB : "查询根节点/全量数据" DB-->>Cache : "原始数据" Cache->>Redis : "序列化并写入缓存" Cache-->>Service : "返回树结构" Service-->>Client : "返回结果" end Note over Service,Cache : "当部门数据变更时,调用失效接口清理对应键" ``` 图表来源 - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) ## 详细组件分析 ### Redis 连接与序列化配置 - 连接配置 - 通过 application.yml 提供主机、端口、密码、数据库索引、超时、连接池等参数 - **已启用密码认证**:在 crm-app 和 crm-auth 模块中均配置了 `spring.redis.password` 字段 - RedisConfig 根据配置创建连接工厂、序列化器与 RedisTemplate - 序列化配置 - 统一使用 JSON 序列化,确保跨语言与可读性 - 对 key/value 分别设置序列化器,避免类型不匹配导致的异常 - 模板装配 - 将 RedisTemplate 注入到需要缓存的业务组件中 - 为常用操作封装统一的读写方法,屏蔽底层细节 **更新** 已在两个应用模块中启用 Redis 密码认证,提升了连接安全性 章节来源 - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) ### 缓存注解使用 - 读缓存 - 使用 @Cacheable 标注在查询方法上,指定缓存名与键表达式 - 首次调用后结果写入缓存,后续相同参数直接命中 - 写缓存 - 使用 @CachePut 在更新方法上同步更新缓存值 - 删除缓存 - 使用 @CacheEvict 在删除或批量修改方法上清理缓存 - 条件缓存 - 通过 condition 与 unless 控制是否缓存及缓存条件 章节来源 - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) ### 自定义缓存组件实现(部门树缓存) - 职责划分 - DeptTreeCache 负责键生成、序列化、缓存读写与失效 - SysDeptServiceImpl 负责业务编排与事务边界 - 键设计 - 基于"业务前缀:实体:维度"原则,例如 dept:tree:all - 支持按租户/环境隔离,避免键冲突 - 数据结构 - 部门树以对象或列表形式序列化存储,便于前端渲染 - 失效策略 - 部门增删改后主动失效对应键;必要时采用延迟双删或版本号策略 - 穿透防护 - 对空结果设置短 TTL 或布隆过滤器前置校验 - 热点键加互斥锁,避免并发击穿 ```mermaid flowchart TD Start(["进入 getDeptTree"]) --> CheckCache["检查缓存键是否存在"] CheckCache --> |存在| ReturnCache["反序列化并返回"] CheckCache --> |不存在| QueryDB["查询数据库"] QueryDB --> DataEmpty{"结果为空?"} DataEmpty --> |是| SetNull["写入空值短TTL防穿透"] DataEmpty --> |否| BuildTree["构建部门树结构"] BuildTree --> Serialize["序列化并写入缓存"] Serialize --> ReturnData["返回数据"] SetNull --> ReturnNull["返回空结果"] ReturnCache --> End(["结束"]) ReturnData --> End ReturnNull --> End ``` 图表来源 - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) 章节来源 - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) ### 缓存键设计策略 - 命名规范 - 统一前缀(如 crm:auth:dept:tree:all),包含系统、模块、实体与用途 - 维度隔离 - 加入租户、环境、版本等维度,避免共享污染 - 稳定性 - 键应稳定可预测,避免动态拼接导致无法定位问题 - 可观测性 - 键中包含必要标识,便于监控与排查 章节来源 - [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) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) ### 缓存穿透防护 - 空值缓存 - 对查无数据的键设置较短 TTL,减少重复回源 - 布隆过滤器 - 在查询前用布隆过滤器判断是否存在,拦截非法 ID - 限流与熔断 - 对异常流量进行限流,防止雪崩 章节来源 - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) ## 依赖关系分析 - 组件耦合 - SysDeptServiceImpl 依赖 DeptTreeCache 完成缓存读写 - DeptTreeCache 依赖 RedisTemplate 进行持久化 - SysDeptMapper 提供数据源 - 外部依赖 - Redis 连接由 RedisConfig 装配,参数来自 application.yml ```mermaid classDiagram class SysDeptServiceImpl { +获取部门树() +更新部门() +删除部门() } class DeptTreeCache { +getDeptTree() +evictDeptTree() +buildKey() } class RedisTemplate { +opsForValue() +opsForHash() +set(key,value,ttl) +get(key) } class SysDeptMapper { +selectDeptList() +insertDept() +updateDept() +deleteDept() } SysDeptServiceImpl --> DeptTreeCache : "调用" DeptTreeCache --> RedisTemplate : "使用" SysDeptServiceImpl --> SysDeptMapper : "数据访问" ``` 图表来源 - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) 章节来源 - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) ## 性能考虑 - 序列化开销 - 优先使用轻量级 JSON 序列化,避免大对象频繁序列化 - 连接池与超时 - 合理设置连接池大小、读写超时与重试次数 - 热点键与广播失效 - 热点键加本地缓存或分布式锁;批量失效采用增量策略 - 内存与过期 - 设置合理的 TTL,避免长期占用内存;定期清理无效键 - 网络与压缩 - 大对象启用压缩;尽量减小往返次数 [本节为通用指导,无需特定文件引用] ## 故障排查指南 - 连接失败 - 检查 application.yml 中的主机、端口、密码、SSL 与超时配置 - **新增**:确认 Redis 密码配置正确,特别是 crm-app 和 crm-auth 模块中的 `spring.redis.password` 字段 - 确认 Redis 服务可达与防火墙策略 - 序列化异常 - 检查 RedisConfig 中 key/value 序列化器是否一致 - 确认实体类实现了必要的序列化接口 - 缓存未命中 - 核对键生成规则与调用方传入参数 - 查看 Redis 中是否存在对应键与 TTL - 数据不一致 - 检查写路径是否执行了失效或双删 - 观察是否有并发更新导致竞态条件 - 监控与调试 - 开启 Redis 慢查询日志 - 增加缓存命中率统计与耗时埋点 **更新** 新增了密码认证相关的故障排查内容 章节来源 - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) - [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) ## 结论 通过统一的 Redis 配置与规范的缓存组件设计,本项目实现了部门树的高效缓存与稳定的失效策略。**已启用密码认证功能**,进一步提升了连接安全性。建议在后续迭代中持续完善键设计与监控指标,结合集群部署与容量规划,进一步提升系统的可用性与性能。 [本节为总结性内容,无需特定文件引用] ## 附录 ### 集群模式配置要点 - 连接模式 - 切换为集群模式,配置节点列表、密码与 SSL - 序列化兼容性 - 确保所有节点使用一致的序列化器 - 路由与分区 - 关注哈希槽分布,避免热点键倾斜 - 高可用 - 启用主从复制与哨兵,设置合适的故障转移策略 [本节为通用指导,无需特定文件引用] ### 缓存监控与调试方法 - 指标采集 - 记录命中率、平均耗时、错误率与内存使用 - 可视化 - 接入监控系统展示趋势与告警 - 调试工具 - 使用 Redis CLI 查看键空间与 TTL - 开启慢查询与日志级别调整 [本节为通用指导,无需特定文件引用] ### 安全配置最佳实践 - 密码管理 - **开发环境**:可使用明文密码(如当前配置) - **生产环境**:务必使用环境变量注入密码,避免硬编码 - 建议使用密钥管理服务(如 Vault、AWS Secrets Manager) - 网络安全 - 启用 Redis TLS/SSL 加密传输 - 配置防火墙规则限制访问来源 - 权限控制 - 为不同环境配置独立的 Redis 数据库 - 使用 ACL 限制命令权限 **新增** 安全配置最佳实践章节,强调生产环境密码管理的注意事项 [本节为通用指导,无需特定文件引用]