9.8 KiB
9.8 KiB
动态数据源延迟加载需求
元数据
- 需求编号:2026-01-21-001
- 创建时间:2026-01-21
- 创建人:SSOT 架构师
- 状态:进行中
- 优先级:高
需求概述
实现动态数据源的延迟加载机制,支持应用启动时只加载主库,从库按需动态加载和切换,从库配置存储在主库中,支持运行时灵活切换从库库名。
目标
- 延迟加载:应用启动时只加载主库数据源,从库数据源在运行时按需加载,减少启动时间和资源占用
- 动态切换:支持运行时动态切换从库库名,无需重启应用
- 配置管理:从库配置信息存储在主库的配置表中,便于统一管理和维护
- 无侵入性:使用现有的
@DataSource注解进行数据源切换,业务代码无需修改
业务上下文
当前问题
- 现有系统在启动时需要加载所有数据源(主库和从库),导致启动时间长
- 从库库名变更需要修改配置文件并重启应用,影响系统可用性
- 多租户场景下,不同租户需要使用不同的从库,现有方案无法支持
业务场景
主库(固定)+ 从库(库名可变)
├─ 主库:存储配置表(包含从库库名)
├─ 从库:启动时不加载,运行时根据配置表动态加载
└─ 操作:更新配置表 → 动态加载从库 → 切换写入数据
应用场景
- 多租户系统:不同租户使用独立的从库,租户切换时动态切换数据源
- 数据归档:历史数据存储在不同从库中,根据时间切换数据源
- 读写分离:主库写数据,从库读数据,从库可动态切换
- 数据迁移:数据迁移期间,可动态切换到新数据库
涉众分析
| 角色 | 需求 | 影响 |
|---|---|---|
| 系统管理员 | 能够通过配置管理从库信息,支持动态切换 | 降低运维成本,提高系统灵活性 |
| 开发人员 | 使用现有注解即可切换数据源,无需修改业务代码 | 降低开发复杂度,提高开发效率 |
| 最终用户 | 系统启动更快,数据切换无感知 | 提升用户体验 |
| 运维人员 | 支持运行时切换数据库,无需重启应用 | 提高系统可用性,减少停机时间 |
功能需求
核心功能
功能 1:数据源配置管理
- 描述:提供数据源配置的增删改查功能,配置信息存储在主库的
sys_datasource_config表中 - 验收标准:
- 支持新增数据源配置
- 支持修改数据源配置(包括库名、主机、端口、用户名、密码等)
- 支持查询数据源配置
- 支持启用/停用数据源配置
- 配置信息包含:数据源名称、数据库名称、主机地址、端口、用户名、密码、数据库类型、状态、备注等
- 优先级:高
- 依赖关系:依赖主库数据源
功能 2:延迟加载从库
- 描述:应用启动时只加载主库数据源,从库数据源在首次使用时动态加载
- 验收标准:
- 应用启动时只加载 MASTER 数据源
- SLAVE 数据源不加载
- 首次使用从库时,从主库读取配置并动态创建数据源
- 数据源创建成功后注册到动态数据源路由器
- 支持启动时自动加载从库(可选)
- 优先级:高
- 依赖关系:依赖功能 1(数据源配置管理)
功能 3:动态切换从库
- 描述:支持运行时动态切换从库库名,无需重启应用
- 验收标准:
- 支持通过 API 切换从库库名
- 切换流程:更新配置表 → 移除旧数据源 → 创建新数据源 → 注册到路由器
- 切换过程线程安全,不影响其他请求
- 切换失败时回滚到原数据源
- 切换时间 < 1 秒
- 优先级:高
- 依赖关系:依赖功能 1(数据源配置管理)、功能 2(延迟加载从库)
功能 4:数据源路由
- 描述:通过
@DataSource注解实现数据源路由,支持主从库切换 - 验收标准:
- 使用
@DataSource(DataSourceType.MASTER)切换到主库 - 使用
@DataSource(DataSourceType.SLAVE)切换到从库 - AOP 切面自动拦截并切换数据源
- 支持方法级别的数据源切换
- 支持类级别的数据源切换
- 使用
- 优先级:高
- 依赖关系:依赖功能 2(延迟加载从库)
次要功能
功能 5:数据源状态监控
- 描述:提供数据源状态监控功能,包括连接池状态、活跃连接数等
- 验收标准:
- 支持查询数据源连接池状态
- 支持查询数据源活跃连接数
- 支持查询数据源空闲连接数
- 支持查询数据源是否可用
- 优先级:中
- 依赖关系:依赖功能 2(延迟加载从库)
功能 6:多数据库类型支持
- 描述:支持多种数据库类型的数据源配置
- 验收标准:
- 支持 MySQL 数据库
- 支持 PostgreSQL 数据库
- 支持 Oracle 数据库
- 支持扩展其他数据库类型
- 优先级:中
- 依赖关系:依赖功能 1(数据源配置管理)
非功能需求
性能需求
- 响应时间:数据源切换响应时间 < 1 秒
- 吞吐量:支持 1000+ 并发请求
- 并发用户数:支持 500+ 并发用户
- 启动时间:应用启动时间减少 30%(相比启动时加载所有数据源)
安全需求
- 认证方式:使用现有的 Spring Security 认证机制
- 授权机制:只有管理员权限才能操作数据源配置
- 数据加密:数据库密码加密存储
- 审计日志:记录数据源配置变更日志
可用性需求
- 系统可用性:99.9%
- 容错机制:数据源切换失败时自动回滚
- 灾备方案:主库故障时系统降级,只读模式
兼容性需求
- 浏览器兼容性:支持主流浏览器(Chrome、Firefox、Edge、Safari)
- 操作系统兼容性:支持 Windows、Linux、macOS
- 接口兼容性:兼容现有的
@DataSource注解接口
可扩展性需求
- 扩展方式:支持新增数据源配置,无需修改代码
- 负载均衡:支持多个从库数据源的负载均衡(未来扩展)
可维护性需求
- 代码可读性:代码符合项目编码规范,注释完整
- 文档完整性:提供完整的使用文档和 API 文档
- 测试覆盖率:单元测试覆盖率 ≥ 80%
数据需求
数据模型
sys_datasource_config 表结构
sys_datasource_config (数据源配置表)
├─ id (BIGINT) - 主键ID
├─ ds_name (VARCHAR) - 数据源名称(如:SLAVE)
├─ db_name (VARCHAR) - 数据库名称
├─ db_host (VARCHAR) - 数据库主机
├─ db_port (INT) - 数据库端口
├─ username (VARCHAR) - 用户名
├─ password (VARCHAR) - 密码
├─ db_type (VARCHAR) - 数据库类型(mysql/postgresql/oracle等)
├─ status (CHAR) - 状态(0正常 1停用)
├─ remark (VARCHAR) - 备注
├─ create_by (VARCHAR) - 创建者
├─ create_time (DATETIME) - 创建时间
├─ update_by (VARCHAR) - 更新者
└─ update_time (DATETIME) - 更新时间
数据存储需求
- 数据库类型:MySQL 8.3.0
- 存储容量:单表支持 1000 万+ 数据
- 数据备份策略:每日备份,保留 7 天
数据流转需求
应用启动
└─ 加载主库数据源
└─ 不加载从库数据源
运行时使用从库
└─ 读取 sys_datasource_config 表
└─ 创建从库数据源
└─ 注册到 DynamicDataSource
└─ 使用从库
切换从库库名
└─ 更新 sys_datasource_config 表
└─ 移除旧从库数据源
└─ 创建新从库数据源
└─ 注册到 DynamicDataSource
业务规则
- 数据源名称唯一性:数据源名称(ds_name)必须唯一
- 主库不可删除:MASTER 数据源不可删除和停用
- 切换时事务隔离:数据源切换时不能在事务中执行
- 并发安全:数据源切换操作必须线程安全
- 密码加密:数据库密码必须加密存储
- 配置验证:数据源配置修改后必须验证连接有效性
技术约束
- Spring Boot 版本:3.5.7
- Java 版本:21
- 数据库:MySQL 8.3.0
- 连接池:Druid 1.2.27
- ORM 框架:MyBatis 3.5.16
- 必须使用现有的
@DataSource注解:不能引入新的注解或 API
成功标准
- 应用启动时间减少 30%
- 数据源切换响应时间 < 1 秒
- 支持运行时切换从库库名,无需重启应用
- 业务代码无需修改,使用现有
@DataSource注解即可切换数据源 - 单元测试覆盖率 ≥ 80%
- 系统可用性 ≥ 99.9%
风险评估
| 风险 | 影响程度 | 发生概率 | 缓解措施 |
|---|---|---|---|
| 数据源切换失败导致服务不可用 | 高 | 中 | 实现自动回滚机制,切换前备份原配置 |
| 并发切换导致数据源状态不一致 | 中 | 中 | 使用 synchronized 关键字保证线程安全 |
| 密码泄露导致数据库安全风险 | 高 | 低 | 密码加密存储,使用 AES 加密算法 |
| 连接池资源耗尽 | 中 | 中 | 合理配置连接池参数,实现连接池监控 |
| 数据库连接超时 | 中 | 中 | 配置合理的连接超时时间,实现重试机制 |
依赖关系
- 依赖现有的
@DataSource注解和 AOP 切面机制 - 依赖现有的
DataSourceManager数据源管理器 - 依赖现有的
DynamicDataSource动态数据源路由器 - 依赖现有的
DynamicDataSourceContextHolder数据源上下文持有者