druid 连接池出现 关闭的连接 异常处理

druid 连接池出现 关闭的连接 异常处理

文章目录

  • druid 连接池出现 关闭的连接 异常处理
    • 报错日志:
    • 项目异常体现
    • 出现的原因:
    • 解决办法:
    • 解决办法中 druid 配置参数说明:

报错日志:

12:39:04.599 [Druid-ConnectionPool-Destroy-766221240] ERROR com.alibaba.druid.util.JdbcUtils - close statement error
java.sql.SQLRecoverableException: 关闭的连接
	at oracle.jdbc.driver.PhysicalConnection.needLine(PhysicalConnection.java:5389) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.OracleStatement.closeOrCache(OracleStatement.java:1578) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.OracleStatement.close(OracleStatement.java:1563) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.OracleStatementWrapper.close(OracleStatementWrapper.java:94) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at com.alibaba.druid.util.JdbcUtils.close(JdbcUtils.java:84) [druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.pool.vendor.OracleValidConnectionChecker.isValidConnection(OracleValidConnectionChecker.java:88) [druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.pool.DruidAbstractDataSource.validateConnection(DruidAbstractDataSource.java:1346) [druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.pool.DruidDataSource.shrink(DruidDataSource.java:2813) [druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.pool.DruidDataSource$DestroyTask.run(DruidDataSource.java:2562) [druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.pool.DruidDataSource$DestroyConnectionThread.run(DruidDataSource.java:2549) [druid-1.1.10.jar:1.1.10]
12:39:04.760 [Druid-ConnectionPool-Destroy-1073682365] ERROR com.alibaba.druid.util.JdbcUtils - close connection error
java.sql.SQLRecoverableException: IO 错误: Connection reset by peer: socket write error
	at oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:556) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.PhysicalConnection.close(PhysicalConnection.java:3984) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at com.alibaba.druid.filter.FilterChainImpl.connection_close(FilterChainImpl.java:186) ~[druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.filter.stat.StatFilter.connection_close(StatFilter.java:261) ~[druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.filter.FilterChainImpl.connection_close(FilterChainImpl.java:181) ~[druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.close(ConnectionProxyImpl.java:115) ~[druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.util.JdbcUtils.close(JdbcUtils.java:73) [druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.pool.DruidDataSource.shrink(DruidDataSource.java:2797) [druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.pool.DruidDataSource$DestroyTask.run(DruidDataSource.java:2562) [druid-1.1.10.jar:1.1.10]
	at com.alibaba.druid.pool.DruidDataSource$DestroyConnectionThread.run(DruidDataSource.java:2549) [druid-1.1.10.jar:1.1.10]
Caused by: java.net.SocketException: Connection reset by peer: socket write error
	at java.net.SocketOutputStream.socketWrite0(Native Method) ~[?:1.8.0_151]
	at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) ~[?:1.8.0_151]
	at java.net.SocketOutputStream.write(SocketOutputStream.java:155) ~[?:1.8.0_151]
	at oracle.net.ns.DataPacket.send(DataPacket.java:210) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.net.ns.NetOutputStream.flush(NetOutputStream.java:230) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:312) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.net.ns.NetInputStream.read(NetInputStream.java:260) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.net.ns.NetInputStream.read(NetInputStream.java:185) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.net.ns.NetInputStream.read(NetInputStream.java:102) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.T4C7Ocommoncall.doOLOGOFF(T4C7Ocommoncall.java:61) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	at oracle.jdbc.driver.T4CConnection.logoff(T4CConnection.java:543) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
	... 9 more

项目异常体现

项目是使用 tomcat 进行部署的,项目运行一段时间就出现应用僵死,然后在日志中也只看到上方的报错,无其他异常,重启 Tomcat 后又运行正常一段时间后又重复出现。

出现的原因:

网上查到资料说是:应用和数据库之间有一层防火墙。防火墙策略是有设置特定时间未使用的Socket连接将自动关闭。

当数据库连接池中的连接被创建而长时间不使用的情况下,该连接会自动回收并失效,但客户端并不知道,在进行数据库操作时仍然使用的是无效的数据库连接,这样,就导致客户端程序报“ java.sql.SQLException: Io 异常: Connection reset” 或“java.sql.SQLException 关闭的连接”异常。

解决办法:

druid 连接池的解决办法就是创建连接池是一下几个参数设置好:

spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL

解决办法中 druid 配置参数说明:

属性 默认值 备注
testOnBorrow false 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testOnBorrow false 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testWhileIdle false 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
timeBetweenEvictionRunsMillis 单位毫秒 有两个含义:1) Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
validationQuery 用来测试连接是否可用的SQL语句

validationQuery:Druid用来测试连接是否可用的SQL语句,默认值每种数据库都不相同:

数据库类型 sql语句
Mysql SELECT 1
SQLSERVER SELECT 1
ORACLE SELECT ‘x’ FROM DUAL
PostGresql SELECT ‘x’

注意:

连接池配置文件中以上参数都有进行配置,但是程序还是有报错;可以根据报错日志,错定位所使用的连接池,然后定位对应连接池创建的代码,看看是否是创建连接池的时候缺了以上对应的参数配置。

参考:
关于java.sql.SQLRecoverableException: Closed Connection异常的解决方案(转)

Druid配置参数详解-validationQuery

Druid源码分析(六) testOnBorrow,testOnReturn,testWhileIdle

你可能感兴趣的:(数据库,java)