<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>18.15.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
测试代码
Thread(
Runnable {
var druidDataSource: DruidDataSource? = null
val connectBO = ConnectBO("jdbc:oracle:thin:@10.10.xx.xx:1521/rac", "username", "errorpassword")
try {
druidDataSource = createDataSource(connectBO) as DruidDataSource
druidDataSource.getConnection(2_000).use {
println(it)
}
} catch (e: Exception) {
println(String.format("test connect error, url:[%s]", connectBO.url))
} finally {
druidDataSource?.close()
}
}
).start()
Thread.sleep(100_000)
}
fun createDataSource(connectBO: ConnectBO): DataSource {
val props = Properties().apply {
this[DruidDataSourceFactory.PROP_DRIVERCLASSNAME] = oracle.jdbc.OracleDriver::class.qualifiedName!!
this[DruidDataSourceFactory.PROP_USERNAME] = connectBO.username
this[DruidDataSourceFactory.PROP_PASSWORD] = connectBO.password
this[DruidDataSourceFactory.PROP_URL] = connectBO.url
}
props.setProperty(DruidDataSourceFactory.PROP_INITIALSIZE, "1")
return DruidDataSourceFactory.createDataSource(props)
}
data class ConnectBO(val url: String, val username: String, val password: String)
问题现象
连接池中的CreateConnectionThread未正常关闭,持续创建连接并打印报错日志:
十一月 10, 2021 11:16:18 上午 com.alibaba.druid.pool.DruidDataSource error
严重: create connection SQLException, url: jdbc:oracle:thin:@10.10.xx.xx:1521/rac, errorCode 1017, state 72000
java.sql.SQLException: ORA-01017: invalid username/password; logon denied
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494)
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:441)
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:436)
at oracle.jdbc.driver.T4CTTIfun.processError(T4CTTIfun.java:1110)
at oracle.jdbc.driver.T4CTTIoauthenticate.processError(T4CTTIoauthenticate.java:552)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:540)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:256)
at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:501)
at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:1297)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:694)
at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:782)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:39)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:704)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1657)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1723)
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2801)
原因分析
根据异常堆栈:
2021-10-11 11:39:24,343 ERROR - [com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2803)] create connection SQLException, url: jdbc:oracle:thin:@10.10.60.52:1521/pdb1, errorCode 17002, state 08006
java.sql.SQLRecoverableException: IO 错误: The Network Adapter could not establish the connection
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:774)
at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:688)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:39)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:691)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1657)
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1723)
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2801)
Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:523)
at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:521)
at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:660)
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:286)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1438)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:518)
... 6 more
Caused by: java.io.IOException: Operation interrupted, socket connect lapse 0 ms. /10.10.xx.xx 1521 0 1 true
at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:209)
at oracle.net.nt.ConnOption.connect(ConnOption.java:161)
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:470)
... 11 more
Caused by: java.io.InterruptedIOException: Operation interrupted
at oracle.net.nt.TimeoutSocketChannel.handleInterrupt(TimeoutSocketChannel.java:311)
at oracle.net.nt.TimeoutSocketChannel.<init>(TimeoutSocketChannel.java:84)
at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:169)
... 13 more
ojdbc8驱动在TimeoutSocketChannel#handleInterrupt方法中清除了线程中断标志,导致Druid的CreateConnectionThread无法在run方法中正常结束。 使用ojdbc6驱动则没有这个问题,Druid能否处理这种问题呢?