一、多数据源应用场景
在实际开发中,SpringBoot应用连接多个数据库的需求日益普遍,主要应用于以下场景:
- 读写分离架构:主库负责写入,从库负责查询,QPS可提升3-5倍
- 业务分库:订单库、用户库分离,降低单库压力
- 多租户系统:每个租户独立数据库,实现数据隔离
- 异构数据库:MySQL + MongoDB混合使用,满足不同业务需求
二、核心实现方案对比
1. 静态多数据源配置
通过@Primary和@Qualifier注解指定多个数据源,适用于数据源相对固定的场景。
2. 动态数据源路由
基于Spring的AbstractRoutingDataSource实现,通过ThreadLocal存储当前数据源标识,运行时动态切换。这是最灵活的方案。
3. 框架集成方案
使用dynamic-datasource-spring-boot-starter框架,通过注解方式简化配置,推荐生产环境使用。
三、动态数据源配置实战
1. 添加依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
2. YAML配置文件
spring:
datasource:
dynamic:
primary: master # 默认数据源
strict: false # 严格模式
datasource:
master:
url: jdbc:mysql://master-db:3306/app
username: root
password: xxx
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
url: jdbc:mysql://slave-db:3306/app
username: root
password: xxx
driver-class-name: com.mysql.cj.jdbc.Driver
3. 数据源切换注解
@Service
public class UserService {
@DS("master") // 使用主库
public void saveUser(User user) {
userMapper.insert(user);
}
@DS("slave") // 使用从库
public User getUserById(Long id) {
return userMapper.selectById(id);
}
}
四、事务管理解决方案
多数据源环境下的事务管理是核心难点,主要有三种方案:
1. JTA/XA分布式事务
使用Atomikos等工具支持2PC协议,提供强一致性,但配置复杂,性能成本高。
2. ChainedTransactionManager
串联多个本地事务管理器,按顺序提交或反向回滚,适用于对一致性要求较低的场景。
3. Seata分布式事务
seata:
enabled: true
application-id: ${spring.application.name}
tx-service-group: my_tx_group
在业务方法上使用@GlobalTransactional注解实现跨数据源事务。
五、常见问题与解决方案
1. 数据源切换失效
问题:@DS注解不生效,始终使用默认数据源。
解决方案:
- 检查AOP是否被正确扫描
- 确认注解加在public方法上
- 排查多个数据源配置类冲突
- 检查DynamicDataSourceContextHolder是否正确清理
2. 事务内数据源不一致
问题:事务方法中切换数据源失败,所有操作都使用初始数据源。
解决方案:
- 避免在事务方法内切换数据源
- 拆分方法,将需要不同数据源的操作放到独立事务中
- 使用
PROPAGATION_REQUIRES_NEW传播行为开启新事务
3. 连接池配置不生效
问题:Hikari连接池配置不生效。
解决方案:
- SpringBoot 2.x后默认使用HikariCP,需要将
url改为jdbc-url - 或指定连接池类型为Druid
六、性能优化建议
1. 连接池配置
根据读写比例合理配置主从库连接池参数:
- 主库:
maximumPoolSize: 20 - 从库:
maximumPoolSize: 50(读密集型场景)
2. SQL优化
确保SQL语句能够有效利用索引,避免全表扫描。
3. 缓存策略
结合Redis等缓存,减少数据库压力,提升系统性能。
4. 监控告警
定期监控主从延迟、连接池使用情况等关键指标,设置告警阈值。
七、最佳实践总结
- 方案选择:80%场景推荐使用
dynamic-datasource-spring-boot-starter,复杂策略或强控制需求可自研路由。 - 事务管理:避免在事务方法内切换数据源,跨数据源操作需使用分布式事务方案。
- 配置规范:为每个数据源单独配置连接池参数,避免资源浪费。
- 监控保障:建立完善的监控体系,及时发现并处理数据源异常。
通过合理配置和优化,SpringBoot多数据源架构能够有效支撑高并发、高可用的企业级应用系统。