# Caffeine缓存迁移指南 ## 概述 本项目已将原有的Redis缓存替换为基于Caffeine的本地缓存,以提升性能并减少对外部Redis服务的依赖。 ## 主要变更 ### 1. 新增依赖 - 添加了Caffeine 2.9.3依赖 - 保留了Guava依赖用于向后兼容 ### 2. 新增组件 #### Caffeine缓存模板 - `AbstractCaffeineCacheTemplate`: 位于`agileboot-infrastructure`模块 - 提供标准化的Caffeine缓存操作接口 - 支持自动从数据库加载数据 - 包含缓存统计和监控功能 #### Caffeine缓存服务 - `CaffeineCacheService`: 位于`agileboot-domain`模块 - 替换原有的`RedisCacheService` - 管理以下缓存: - 验证码缓存 (`captchaCache`) - 登录用户缓存 (`loginUserCache`) - 用户实体缓存 (`userCache`) - 角色实体缓存 (`roleCache`) - 岗位实体缓存 (`postCache`) #### 缓存配置 - `CaffeineCacheConfig`: 提供Caffeine缓存的全局配置 - 支持自定义缓存参数 ### 3. 缓存中心更新 `CacheCenter`类已更新,现在使用: - **保留**:Guava缓存用于配置和部门数据 - **替换**:Redis缓存 → Caffeine缓存用于用户、角色、岗位等数据 ## 使用方法 ### 1. 获取缓存数据 ```java // 从缓存中获取用户数据 SysUserEntity user = CacheCenter.userCache.get("1"); // 从缓存中获取角色数据 SysRoleEntity role = CacheCenter.roleCache.get("1"); ``` ### 2. 使缓存失效 ```java // 使单个缓存失效 CacheCenter.userCache.invalidate("1"); // 使所有缓存失效 CacheCenter.userCache.invalidateAll(); ``` ### 3. 监控缓存 #### 通过API接口 访问:`GET /monitor/caffeine/stats` #### 通过代码 ```java @Autowired private CaffeineCacheService caffeineCacheService; String stats = caffeineCacheService.getCacheStats(); System.out.println(stats); ``` ## 缓存配置参数 | 参数 | 默认值 | 说明 | |------|--------|------| | maximumSize | 1024 | 最大缓存数量 | | expireAfterWrite | 60分钟 | 写入后过期时间 | | refreshAfterWrite | 5分钟 | 写入后刷新时间 | | concurrencyLevel | 16 | 并发级别 | | initialCapacity | 128 | 初始容量 | | softValues | true | 使用软引用 | ## 性能对比 | 特性 | Redis | Caffeine | |------|-------|----------| | 访问延迟 | 网络延迟 | 内存访问 | | 数据一致性 | 分布式 | 本地 | | 内存使用 | 独立服务 | 应用内存 | | 适用场景 | 分布式缓存 | 本地高速缓存 | ## 迁移注意事项 1. **数据一致性**:Caffeine是本地缓存,多实例部署时数据可能不一致 2. **内存使用**:监控应用内存使用情况,避免缓存过多数据 3. **缓存失效**:确保在数据更新时正确使缓存失效 4. **监控**:定期检查缓存命中率和统计信息 ## 回滚方案 如需回滚到Redis缓存: 1. 恢复`CacheCenter`中的Redis缓存引用 2. 移除Caffeine相关依赖 3. 重启应用 ## 故障排查 ### 常见问题 1. **缓存不生效**:检查`@PostConstruct`方法是否正确初始化 2. **内存溢出**:调整`maximumSize`和`expireAfterWrite`参数 3. **数据不一致**:确保数据更新时正确调用`invalidate`方法 ### 调试方法 ```java // 查看缓存统计 System.out.println(CacheCenter.userCache.getStats()); // 手动触发缓存加载 CacheCenter.userCache.get("test-key"); ```