在实际生产中,会有数据库主备切换的需要,当主数据库宕机时,或者主网卡无法连接时,希望程序能够自动切换到备机或备网卡上。
通过对DruidDatasource创建物理连接的源码分析,DruidDatasource在每次尝试建立与数据库的物理连接时,都会通过getUrl()方法读取参数jdbcUrl。
通过对外层代码的分析,在连接发生异常时,并且我们配置了重试参数connectionErrorRetryAttempts和timeBetweenConnectErrorMillis时。当达到配置好的重试上限次数后,DruidDatasource会调用方法setFailContinuous,将参数failContinuous设置为true。在需要稳定重试的连接中,我们会设置参数breakAfterAcquireFailure为false。DruidDatasource会在预设的timeBetweenConnectErrorMillis后再次拉起重试。
根据以上源码分析,我们可以提出一种可行的方案。
通过继承DruidDatasource并改写setFailContinuous()方法和增加获取备用url的方法,当DruidDatasource持续重连并且失败达到一定次数后,进入setFailContinuous()。除原有逻辑外,额外将DruidDatasource的jdbcUrl改为备用数据库的Url。
示例代码如下:
@Override
protected void setFailContinuous(boolean fail) {
super.setFailContinuous(fail);
if (isBackup && fail) {
this.jdbcUrl = haService.getBackUpUrl();
}
}
经过如下改造后,在经过timeBetweenConnectErrorMillis后DruidDatasource再次拉起时,会使用新的jdbcUrl创建数据库物理连接。达到连接自动切换主备的效果。