Files
loan-pricing/doc/2026-03-28-remove-redis-design.md

7.7 KiB
Raw Blame History

生产环境移除 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 配置
  • 移除 RedisTemplateRedisConnectionFactory、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. 后续输出

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

  • 后端实施计划
  • 前端实施计划

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