You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
15 KiB

1 month ago
# 缓存配置
<cite>
**本文引用的文件**
- [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)
1 month ago
- [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)
</cite>
## 更新摘要
**所做更改**
- 更新了 Redis 连接配置部分,反映密码认证已启用的变更
- 在故障排查指南中增加了密码认证相关的排查内容
- 更新了安全配置建议,强调生产环境密码管理最佳实践
1 month ago
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件围绕项目的缓存配置与使用进行系统化说明,重点覆盖:
- Redis 连接与序列化配置要点(包含密码认证配置)
1 month ago
- 缓存注解的使用方式(如 @Cacheable/@CacheEvict
- 自定义缓存组件实现(以部门树缓存为例)
- 缓存键设计策略、失效机制与穿透防护
- 性能优化建议、集群模式配置、监控与调试方法
## 项目结构
本项目采用多模块组织,缓存相关能力集中在基础模块的 Redis 配置中,业务模块通过服务层与自定义缓存组件进行使用。关键路径如下:
- 基础配置:RedisConfig.java
- 应用配置:crm-app/application.yml, crm-auth/application.yml
1 month ago
- 业务缓存: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"]
1 month ago
end
subgraph "认证模块"
D["DeptTreeCache.java"]
E["SysDeptServiceImpl.java"]
F["SysDeptMapper.java"]
1 month ago
end
B --> A
C --> A
E --> D
D --> A
E --> F
1 month ago
```
图表来源
- [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)
1 month ago
- [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)
1 month ago
## 核心组件
- Redis 配置类:负责连接工厂、序列化器、模板装配等
- 应用配置文件:集中管理 Redis 连接参数、超时、序列化等(包含密码认证)
1 month ago
- 部门树缓存组件:封装部门树的读取、写入、失效与键生成逻辑
- 部门服务实现:在查询与更新时调用缓存组件,保证一致性
章节来源
- [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)
1 month ago
- [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` 字段
1 month ago
- RedisConfig 根据配置创建连接工厂、序列化器与 RedisTemplate
- 序列化配置
- 统一使用 JSON 序列化,确保跨语言与可读性
- 对 key/value 分别设置序列化器,避免类型不匹配导致的异常
- 模板装配
- 将 RedisTemplate 注入到需要缓存的业务组件中
- 为常用操作封装统一的读写方法,屏蔽底层细节
**更新** 已在两个应用模块中启用 Redis 密码认证,提升了连接安全性
1 month ago
章节来源
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [application.yml](file://crm-auth/src/main/resources/application.yml)
1 month ago
- [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
1 month ago
- 支持按租户/环境隔离,避免键冲突
- 数据结构
- 部门树以对象或列表形式序列化存储,便于前端渲染
- 失效策略
- 部门增删改后主动失效对应键;必要时采用延迟双删或版本号策略
- 穿透防护
- 对空结果设置短 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` 字段
1 month ago
- 确认 Redis 服务可达与防火墙策略
- 序列化异常
- 检查 RedisConfig 中 key/value 序列化器是否一致
- 确认实体类实现了必要的序列化接口
- 缓存未命中
- 核对键生成规则与调用方传入参数
- 查看 Redis 中是否存在对应键与 TTL
- 数据不一致
- 检查写路径是否执行了失效或双删
- 观察是否有并发更新导致竞态条件
- 监控与调试
- 开启 Redis 慢查询日志
- 增加缓存命中率统计与耗时埋点
**更新** 新增了密码认证相关的故障排查内容
1 month ago
章节来源
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [application.yml](file://crm-auth/src/main/resources/application.yml)
1 month ago
- [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 配置与规范的缓存组件设计,本项目实现了部门树的高效缓存与稳定的失效策略。**已启用密码认证功能**,进一步提升了连接安全性。建议在后续迭代中持续完善键设计与监控指标,结合集群部署与容量规划,进一步提升系统的可用性与性能。
1 month ago
[本节为总结性内容,无需特定文件引用]
## 附录
### 集群模式配置要点
- 连接模式
- 切换为集群模式,配置节点列表、密码与 SSL
- 序列化兼容性
- 确保所有节点使用一致的序列化器
- 路由与分区
- 关注哈希槽分布,避免热点键倾斜
- 高可用
- 启用主从复制与哨兵,设置合适的故障转移策略
[本节为通用指导,无需特定文件引用]
### 缓存监控与调试方法
- 指标采集
- 记录命中率、平均耗时、错误率与内存使用
- 可视化
- 接入监控系统展示趋势与告警
- 调试工具
- 使用 Redis CLI 查看键空间与 TTL
- 开启慢查询与日志级别调整
[本节为通用指导,无需特定文件引用]
### 安全配置最佳实践
- 密码管理
- **开发环境**:可使用明文密码(如当前配置)
- **生产环境**:务必使用环境变量注入密码,避免硬编码
- 建议使用密钥管理服务(如 Vault、AWS Secrets Manager)
- 网络安全
- 启用 Redis TLS/SSL 加密传输
- 配置防火墙规则限制访问来源
- 权限控制
- 为不同环境配置独立的 Redis 数据库
- 使用 ACL 限制命令权限
**新增** 安全配置最佳实践章节,强调生产环境密码管理的注意事项
1 month ago
[本节为通用指导,无需特定文件引用]