# 生产环境移除 Redis 依赖设计文档

## 1. 背景

当前项目基于若依前后端分离架构，Redis 在系统中承担了多类运行时状态能力，包括：

- JWT 登录态缓存
- 验证码缓存
- 登录失败次数缓存
- 防重提交短期缓存
- 接口限流计数
- 系统配置缓存
- 数据字典缓存
- 在线用户查询与强退
- 缓存监控页面与缓存清理接口

现有生产环境没有 Redis，因此需要彻底移除 Redis 依赖，并保证修改后与修改前的业务功能保持一致。

## 2. 已确认约束

- 生产环境为单实例部署
- 应用重启后，登录态、验证码、限流计数、登录失败次数等临时状态允许丢失
- 不引入新的中间件
- 不额外设计数据库持久化方案
- 目标是最短路径实现，避免补丁式和过度设计方案

## 3. 目标

- 移除 Redis 运行依赖与相关配置
- 保留现有业务功能与主要接口行为
- 保留现有前端缓存监控入口与主要能力
- 保证项目在无 Redis 配置、无 Redis 服务的情况下可正常启动和运行

## 4. 方案对比

### 方案一：统一进程内缓存层替换 Redis

将当前基于 Redis 的缓存访问统一收口为进程内缓存实现，保持上层业务调用方式和缓存语义尽量不变。

优点：

- 改动集中，替换边界清晰
- 最容易保持原有业务行为不变
- 不需要引入新基础设施
- 适合单实例部署场景

缺点：

- 需要补足 TTL、前缀查询、统计信息等基础能力
- 限流逻辑需要从 Redis 脚本改为本地原子实现

### 方案二：按场景分别重写

登录态、验证码、配置缓存、字典缓存、限流、防重分别改造成各自独立的本地实现。

优点：

- 单点改造直观

缺点：

- 改动分散
- 行为一致性难保证
- 容易遗漏使用点
- 后续维护成本更高

### 方案三：部分状态改存数据库

将登录态、验证码、失败次数等状态迁移到 MySQL。

优点：

- 状态具备一定持久性

缺点：

- 偏离本次最短路径目标
- 需要新增表结构、清理逻辑和一致性处理
- 复杂度明显高于当前需求

## 5. 设计结论

采用方案一：以统一进程内缓存层替换 Redis。

实现原则：

- 保留当前主要业务调用入口，避免业务层大面积改写
- 将所有 Redis 依赖集中替换为本地线程安全缓存实现
- 保持 key 组织方式、TTL 语义、按前缀检索、删除和清理行为不变
- 对外接口路径尽量不变，优先保障现有前后端功能连续性

## 6. 总体设计

### 6.1 基础设施替换边界

本次改造不采用“逐处删除 Redis 调用”的方式，而是保留当前缓存入口职责，将底层从 Spring Data Redis 替换为进程内缓存服务。

范围包括：

- 移除 `spring-boot-starter-data-redis` 依赖
- 移除 `application-*.yml` 中的 Redis 配置
- 移除 `RedisTemplate`、`RedisConnectionFactory`、Lua 限流脚本等 Redis 专属配置
- 为现有缓存访问入口提供本地实现

### 6.2 本地缓存能力要求

本地缓存组件必须提供以下能力：

- `set`
- `get`
- `hasKey`
- `delete`
- 批量删除
- 基于前缀的 `keys(pattern*)`
- TTL 过期控制
- 过期数据清理
- 基础命中和访问统计

该缓存实现需要线程安全，以保证登录、限流、防重提交等高频路径在单实例下的正确性。

## 7. 业务行为兼容设计

### 7.1 登录态

`TokenService` 当前通过 JWT 保存 token 标识，并将 `LoginUser` 存入 Redis。改造后继续维持该模型：

- JWT 内容保持不变
- `token -> LoginUser` 存入本地缓存
- TTL 仍由 `token.expireTime` 控制
- 临近过期时继续自动续期
- 注销时删除对应登录态

这样可以保持登录、鉴权、刷新 token、在线用户列表、强退用户等行为不变。

### 7.2 验证码

验证码继续按 `uuid -> code` 存储在本地缓存中，并沿用当前过期时间配置。

- 生成验证码后写入缓存
- 校验时读取并删除
- 过期后自动失效

### 7.3 登录失败次数

登录失败次数继续按用户名缓存，保持：

- 连续失败次数累加
- 达到阈值后锁定
- 锁定时间到期后自动解除
- 登录成功后清理失败记录

### 7.4 防重提交

`SameUrlDataInterceptor` 继续按 `url + submitKey` 保存短时缓存，保留当前毫秒级过期控制和重复提交判断逻辑。

### 7.5 限流

原有限流逻辑依赖 Redis Lua 脚本做原子计数。由于当前部署为单实例，可以改为本地原子计数实现，保留现有注解参数语义：

- 限流 key 规则不变
- 时间窗口含义不变
- 阈值含义不变
- 超限返回逻辑不变

### 7.6 系统配置缓存

`SysConfigServiceImpl` 继续通过缓存保存系统配置，保持：

- 启动加载缓存
- 按 key 读取缓存
- 新增、修改、删除配置时同步刷新缓存
- 手动刷新缓存接口继续可用

### 7.7 数据字典缓存

`DictUtils` 与字典服务继续使用缓存保存字典数据，保持：

- 首次加载与重载逻辑不变
- 字典刷新接口不变
- 前端字典相关功能无感知

### 7.8 在线用户

在线用户列表和强退功能继续基于登录 token 前缀扫描实现，因此本地缓存必须支持按前缀查询 key。

### 7.9 缓存监控

不删除缓存监控功能。保留：

- 菜单入口
- 前端页面路由
- 后端接口路径
- 缓存清理能力

底层统计来源从 Redis 改为本地缓存统计视图。

## 8. 缓存监控设计

### 8.1 保留现有能力

`CacheController` 继续提供以下接口能力：

- 缓存概览
- 缓存名称列表
- 指定分类下的 key 列表
- 指定 key 的值查看
- 按分类清理
- 按 key 清理
- 全量清理

### 8.2 监控数据来源调整

由于 Redis 已移除，缓存监控页面中的信息调整为本地缓存统计信息，例如：

- 缓存类型：`IN_MEMORY`
- 运行模式：`single-instance`
- 当前缓存总数
- 读取次数
- 命中次数
- 过期清理次数

返回结构应尽量兼容当前前端页面，减少前端改动范围。

### 8.3 文案调整

对于前端页面中明显写死的 Redis 文案，需要调整为更准确的“缓存监控”或“本地缓存监控”，避免出现界面语义错误。

## 9. 配置与依赖调整

需要完成以下调整：

- 删除 Maven 中 Redis 相关依赖
- 删除后端配置中的 Redis 段
- 清理 Redis 专属配置类与序列化器引用
- 清理直接依赖 `RedisTemplate` 的控制器和切面实现
- 将相关逻辑改为依赖统一的本地缓存服务

## 10. 测试与验收

验收以业务行为为准，至少覆盖：

- 登录成功后可访问受保护接口
- token 临近过期时自动续期正常
- 在线用户列表可查询
- 在线用户强退可用
- 验证码生成与校验正常
- 登录失败次数限制正常
- 防重提交正常
- 限流正常
- 配置缓存刷新正常
- 字典缓存刷新正常
- 缓存监控页面可打开、可查看、可清理
- 项目在无 Redis 配置、无 Redis 服务时可启动

## 11. 风险与边界

- 本方案仅适用于当前确认的单实例部署
- 由于缓存改为进程内存储，多实例部署时不会共享状态
- 重启后临时状态会丢失，此行为已被确认可接受
- 本次不增加跨实例一致性能力，不增加持久化方案

## 12. 实施范围说明

本设计文档仅定义 Redis 移除与本地缓存替换方案，不扩展到以下范围：

- 多实例一致性方案
- 引入数据库持久化缓存
- 引入新的第三方缓存组件
- 额外新增降级或兜底机制

## 13. 后续输出

在该设计确认后，下一步需要输出两份实施计划：

- 后端实施计划
- 前端实施计划

并在实际编码改动时同步维护对应实施记录文档。
