Java 数据库连接池怎么配置连接池负载均衡
java 原生 jdbc 和常见的连接池(如 hikaricp、druid)本身并不直接提供多数据源的自动负载均衡功能,它们主要管理单个数据源的健康状态。要实现负载均衡,必须在应用层或中间件层引入多数据源路由机制,通常的做法是结合 spring 的 abstractroutingdatasource 动态切换目标数据源,或者使用 shardingsphere 等中间件进行读写分离和分片。对于简单的读写分离场景,可以将读请求路由到从库,写请求路由到主库;对于更复杂的负载均衡,需要自定义 keygenerator 或基于元数据(如连接数、延迟)动态选择数据源。

如何通过代码实现动态数据源路由
在 Spring Boot 项目中,可以通过继承 AbstractRoutingDataSource 类来实现动态数据源的路由。核心思路是维护一个目标数据源键(Target DataSource Key)的线程本地变量(ThreadLocal),并在每次数据库操作前设置该键,连接池根据该键获取对应的物理连接。这种方式允许在运行时根据业务逻辑(如用户 ID 哈希、事务类型等)决定使用哪个数据库实例。

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}上述代码中,determineCurrentLookupKey 方法返回当前线程绑定的数据源标识。配合 DataSourceContextHolder 工具类,可以在 Service 层通过 AOP 或手动调用 DataSourceContextHolder.setDataSourceType("slave") 来切换读库。Spring 容器会将配置好的主从数据源 Map 注入到 DynamicDataSource 的 targetDataSources 属性中,默认数据源设置为 defaultTargetDataSource。
立即学习“Java免费学习笔记(深入)”;
如何验证多数据源切换的实际效果
为了验证动态数据源是否生效,可以编写一个简单的测试用例,模拟一次写操作和一次读操作。写操作强制使用主库(Master),读操作强制使用从库(Slave)。通过观察日志输出或数据库审计日志,确认 SQL 语句确实被发送到了不同的物理连接上。如果未正确配置 AbstractRoutingDataSource 或忘记清除 ThreadLocal 变量,可能导致连接泄漏或路由错误。

@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void saveUser(User user) {
DataSourceContextHolder.setDataSourceType("master");
try {
jdbcTemplate.update("INSERT INTO users ...", user);
} finally {
DataSourceContextHolder.clear();
}
}
public User getUser(Long id) {
DataSourceContextHolder.setDataSourceType("slave");
try {
return jdbcTemplate.queryForObject("SELECT * FROM users WHERE id = ?", new Object[]{id}, User.class);
} finally {
DataSourceContextHolder.clear();
}
}
}


















