Hikari高可用数据库配置:自动故障转移实现方案
HikariCP实现Oracle主备库自动切换方案
可以实现主库宕机时自动切换到备库,但HikariCP本身没有内置主备切换逻辑,需要结合Oracle原生特性或自定义配置来完成,以下是两种常用方案:
方案一:基于Oracle TAF(Transparent Application Failover)原生故障转移
这是最简便的方案,利用Oracle自带的TAF机制实现透明故障转移,HikariCP只需适配配置即可:
- 配置Oracle TNS连接串
在Oracle客户端的tnsnames.ora中配置包含主备库的TAF连接:
ORCL_TAF = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = primary-db-ip)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = standby-db-ip)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = your_service_name) (FAILOVER_MODE = (TYPE = SELECT) # 针对查询操作的故障转移 (METHOD = BASIC) # 连接建立时启用故障转移 (RETRIES = 180) # 重试次数 (DELAY = 5) # 重试间隔(秒) ) ) )
- SpringBoot HikariCP配置
在application.yml中指定使用上述TAF连接串:
spring: datasource: hikari: jdbc-url: jdbc:oracle:thin:@ORCL_TAF username: your_db_user password: your_db_pwd maximum-pool-size: 10 connection-timeout: 30000 # 可选:配置连接测试,确保连接有效性 connection-test-query: SELECT 1 FROM DUAL
原理:TAF会在主库故障时自动将现有连接切换到备库,HikariCP无需感知底层切换,对应用完全透明。
方案二:自定义动态路由数据源(无TAF时使用)
如果无法使用Oracle TAF,可以通过自定义路由数据源结合HikariCP的连接检测来实现切换:
- 配置主备两个Hikari连接池
在application.yml中定义主备数据源参数:
spring: datasource: primary: hikari: jdbc-url: jdbc:oracle:thin:@//primary-db-ip:1521/your_service username: your_db_user password: your_db_pwd maximum-pool-size: 10 standby: hikari: jdbc-url: jdbc:oracle:thin:@//standby-db-ip:1521/your_service username: your_db_user password: your_db_pwd maximum-pool-size: 10
- 实现动态路由数据源
继承Spring的AbstractRoutingDataSource,实现主库状态检测与路由逻辑:
@Component public class DynamicDatasource extends AbstractRoutingDataSource { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Autowired @Qualifier("standbyDataSource") private DataSource standbyDataSource; @Override public void afterPropertiesSet() { // 设置目标数据源映射 Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("primary", primaryDataSource); targetDataSources.put("standby", standbyDataSource); setTargetDataSources(targetDataSources); setDefaultTargetDataSource(primaryDataSource); super.afterPropertiesSet(); } @Override protected Object determineCurrentLookupKey() { // 检测主库是否可用,不可用则切换到备库 return isPrimaryAvailable() ? "primary" : "standby"; } private boolean isPrimaryAvailable() { try (Connection conn = primaryDataSource.getConnection()) { // 执行简单SQL检测连接有效性 try (Statement stmt = conn.createStatement()) { stmt.executeQuery("SELECT 1 FROM DUAL").close(); return true; } } catch (SQLException e) { // 主库连接失败,返回false切换到备库 return false; } } }
- 配置主备数据源Bean
创建配置类注册主备Hikari数据源:
@Configuration public class DatasourceConfig { @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary.hikari") public DataSource primaryDataSource() { return new HikariDataSource(); } @Bean(name = "standbyDataSource") @ConfigurationProperties(prefix = "spring.datasource.standby.hikari") public DataSource standbyDataSource() { return new HikariDataSource(); } }
注意:这种方式需要自行处理故障恢复后的切回逻辑(比如定时检测主库是否恢复,自动切回),可以通过定时任务实现。
方案对比
- 优先选择Oracle TAF方案:配置简单、无需代码开发、对应用透明,是Oracle主备故障转移的原生最优解。
- 自定义路由方案:适用于无法使用TAF的场景,但需要额外开发状态检测与路由逻辑,复杂度较高。
内容的提问来源于stack exchange,提问作者Rakesh V
相关产品推荐
相关产品推荐

